Re: [RFC PATCH] Consolidate SRAM support

2011-04-16 Thread Haojian Zhuang
On Fri, Apr 15, 2011 at 9:06 PM, Russell King - ARM Linux
li...@arm.linux.org.uk wrote:
 This is work in progress.

 We have two SoCs using SRAM, both with their own allocation systems,
 and both with their own ways of copying functions into the SRAM.

 Let's unify this before we have additional SoCs re-implementing this
 obviously common functionality themselves.

 Unfortunately, we end up with code growth through doing this, but that
 will become a win when we have another SoC using this (which I know
 there's at least one in the pipeline).

 One of the considerations here is that we can easily convert sram-pool.c
 to hook into device tree stuff, which can tell the sram allocator:
        - physical address of sram
        - size of sram
        - allocation granularity
 and then we just need to ensure that it is appropriately mapped.

 This uses the physical address, and unlike Davinci's dma address usage,
 it always wants to have the physical address, and will always return
 the corresponding physical address when passed that pointer.

 OMAP could probably do with some more work to make the omapfb and other
 allocations use the sram allocator, rather than hooking in before the
 sram allocator is initialized - and then further cleanups so that we
 have an initialization function which just does

 sram_create(phys, size)
        virt = map sram(phys, size)
        create sram pool(virt, phys, size, min_alloc_order)

 Another question is whether we should allow multiple SRAM pools or not -
 this code does allow multiple pools, but so far we only have one pool
 per SoC.  Overdesign?  Maybe, but it prevents SoCs wanting to duplicate
 it if they want to partition the SRAM, or have peripheral-local SRAMs.

 Lastly, uio_pruss should probably take the SRAM pool pointer via
 platform data so that it doesn't have to include Davinci specific
 includes.

 Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk

This common sram driver is good for us. It can benefit us on DMA usage.
I just have one question on SRAM for storing instruction. We still need to
copy code into SRAM and flush cache  TLB with this SRAM driver.

TCM driver can allocate code into SRAM section in link stage. It needs to
update link file and virtual memory layout. Is it worth to make SRAM driver
support this behavior? The case of using SRAM as memory for instruction
is switching frequency or entering/exiting low power mode in PXA silicons.

Thanks
Haojian
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH] Consolidate SRAM support

2011-04-16 Thread Russell King - ARM Linux
On Sat, Apr 16, 2011 at 09:01:26PM +0800, Haojian Zhuang wrote:
 On Fri, Apr 15, 2011 at 9:06 PM, Russell King - ARM Linux
 li...@arm.linux.org.uk wrote:
  This is work in progress.
 
  We have two SoCs using SRAM, both with their own allocation systems,
  and both with their own ways of copying functions into the SRAM.
 
  Let's unify this before we have additional SoCs re-implementing this
  obviously common functionality themselves.
 
  Unfortunately, we end up with code growth through doing this, but that
  will become a win when we have another SoC using this (which I know
  there's at least one in the pipeline).
 
  One of the considerations here is that we can easily convert sram-pool.c
  to hook into device tree stuff, which can tell the sram allocator:
         - physical address of sram
         - size of sram
         - allocation granularity
  and then we just need to ensure that it is appropriately mapped.
 
  This uses the physical address, and unlike Davinci's dma address usage,
  it always wants to have the physical address, and will always return
  the corresponding physical address when passed that pointer.
 
  OMAP could probably do with some more work to make the omapfb and other
  allocations use the sram allocator, rather than hooking in before the
  sram allocator is initialized - and then further cleanups so that we
  have an initialization function which just does
 
  sram_create(phys, size)
         virt = map sram(phys, size)
         create sram pool(virt, phys, size, min_alloc_order)
 
  Another question is whether we should allow multiple SRAM pools or not -
  this code does allow multiple pools, but so far we only have one pool
  per SoC.  Overdesign?  Maybe, but it prevents SoCs wanting to duplicate
  it if they want to partition the SRAM, or have peripheral-local SRAMs.
 
  Lastly, uio_pruss should probably take the SRAM pool pointer via
  platform data so that it doesn't have to include Davinci specific
  includes.
 
  Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
 
 This common sram driver is good for us. It can benefit us on DMA usage.
 I just have one question on SRAM for storing instruction. We still need to
 copy code into SRAM and flush cache  TLB with this SRAM driver.

There is the fncpy API for copying code to other regions of memory,
including SRAM.  The fncpy API is explicitly designed to cope with
Thumb 2 and provide an appropriate function pointer for such code.

Such code needs to be position independent to cope with multiple SRAM
users, and also possible variability of SRAM mapping which may (eventually)
exist when DT comes along.

 TCM driver can allocate code into SRAM section in link stage. It needs to
 update link file and virtual memory layout. Is it worth to make SRAM driver
 support this behavior? The case of using SRAM as memory for instruction
 is switching frequency or entering/exiting low power mode in PXA silicons.

This is more or less the same scenario which OMAP is using its SRAM
for, although that's explicitly SRAM and not TCM.

I don't think we need position dependent code requiring fixup for
these applications as such things tend to be fairly easily coded in a
position independent way.

Also note that C functions can't be copied because C produces position
dependent code, and we have no way of extracting the relocation
dependencies from such code.
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 00/11] dmtimer adaptation to platform_driver

2011-04-16 Thread Tarun Kanti DebBarma
dmtimer adaptation to platform_driver.

This patch series is adaptation of dmtimer code to platform driver
using omap_device and omap_hwmod abstraction.

Baseline:
git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git
Branch: devel-timer

Test Info:
* OMAP4430SDP: Functional tests done.
* OMAP3430SDP: Functional tests done 
* OMAP2420SDP: Functional tests done
* OMAP1710SDP: Build test done. Boot test pending.

v13:
(1) Handling of early timer removed because this is being taken care by
Tony's patch series.
(2) Timers reserved for clockevent/clocksource during early boot are
registered and marked reserved.
(3) Platform specific timer code merged to mach-omap2/timer.c.
(4) Timer capabilities are added in the hwmod database to each of the
omap timers.
(5) plat-omap/dmtimer.c plat-omap/include/plat/dmtimer.h are converted
to a driver by moving them to drivers/misc/timer-omap.c and 
include/linux/timer-omap.h

v12:
(1) Remove registration and initialization of all timers during early boot.
Initialize only the system timer which is set by the board file or default
value assigned to it. This timer is not considered later during rest of the
timers initialization.

(2) Use mutex instead of spinlock since there is no interrupt context.

(3) Remove hacky code to manage GPTIMER12 in mach-omap2/dmtimer.c. This is
now changed to use dev_attr instead to identify if it is a secure timer.
In the hwmod database, any secure timer entry can use this dev_attr so that
driver avoids registering tha particular timer.

(4) Removed reset function from OMAP1 and kept it back to its original place
in plat-omap/dmtimer.c, with modification of course. Instead of (is_omap16xx)
flag a new variable (needs_manual_reset) added. This flag is set for OMAP1.
So, call to reset function is made if this value is set implying that reset
is called only for OMAP1.

(5) Timer enable and disable functions cleanup with checks for early boot
condition removed. Added new interface wrapper function to configure
system timer clock source.

(6) Move OMAP4 specific register offsets from mach-omap2 to driver code
along with other register offset definitions.

(7) omap2_dm_timer_early_init() renamed to omap2_system_timer_init(),
omap2_dm_timer_normal_init() renamed to omap2_dm_timer_init().

(8) Use dev_err() instead of pr_err() in low level read/write functions.

TODO:
Somehow pm_runtime_suspended() does not seem to be working as expected
when used in omap_dm_timer_enable() and omap_dm_timer_disable().
Because of this the 'enabled' flag could not be eliminated.


v11:
(1) Removed early timer initialization call from omap2_init_common_devices()
in io.c. It is now called from omap2_gp_timer_init() in timer-gp.c as part
of following call sequence:
start_kernel()-time_init()-timer-init()-omap2_gp_timer_init()
(2) Basedlined on top of Paul's patch series mentioned above.

v10:
(1) Update PM runtime for active early timers so that PM runtime userspace
info is correct.
(2) Include code to configure timers to POSTED mode which got missed in
the previous version.
(3) Remove pm runtime_enable from OMAP1 specific code since this is not
applicable.

v9:
(1) In OMAP3 hwmod database, added entry for timer12 which was missing.
Beagle board uses timer12 as its millisecond timer.
(2) In OMAP3 hwmod database, rectified in-correct prcm configurations
for timer10 and timer11.
From:
   .prcm   = {
   .module_bit = OMAP24XX_EN_GPT10_SHIFT,
   .idlest_idle_bit = OMAP24XX_ST_GPT10_SHIFT,
   },
To:
   .prcm   = {
   .module_bit = OMAP3430_EN_GPT10_SHIFT,
   .idlest_idle_bit = OMAP3430_ST_GPT10_SHIFT,
   },
(3) In OMAP3 hwmod database, removed timer master port entry for all
timers because it is not supported.

static struct omap_hwmod_ocp_if *omap3xxx_timer7_masters[] = {
   omap3xxx_l4_per__timer7,
};

(4) In OMAP4 hwmod database, added SIDLE_SMART_WKUP flag for
non-millisecond timers.
(5) In OMAP3 hwmod database, rectified sysconfig configuration for
non-millisecond timers.
From: omap_hwmod_sysc_type2 To: omap_hwmod_sysc_type1.
This was preventing system to go to RETENTION and OFF modes.

v8:
(1) Baselined on Tony's tree in omap-for-linus branch
(2) The last patch in v7 series has been removed because it is fixed
by following patch:
commit: 78f26e872f77b6312273216de1a8f836c6f2e143
OMAP: hwmod: Set autoidle after smartidle during _sysc_enable

v7:
(1) In omap1_dm_timer_set_src(), the computation of shift value to respective
dmtimer clock source was corrected:
From:
int n = (pdev-id)  1;
To:
int n = (pdev-id - 1)  1;
This change is needed because dmtimer is indexed from 1 now instead of 0.
(2) In  omap1_dm_timer_init(void) memory resource end address chnaged:
From:
res[0].end = base + 0xff;
To:
res[0].end = base + 0x46;
This was causing request_mem_region() failure in driver probe().
(3) In the export APIs there are some calls which are not 

[PATCH v13 01/11] OMAP2+: dmtimer: add device names to flck nodes

2011-04-16 Thread Tarun Kanti DebBarma
Add device name to OMAP2 dmtimer fclk nodes so that the fclk nodes can be
retrieved by doing a clk_get with the corresponding device pointers or
device names.

Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com
Signed-off-by: Thara Gopinath th...@ti.com
Acked-by: Cousson, Benoit b-cous...@ti.com
---
 arch/arm/mach-omap2/clock2420_data.c |   52 -
 arch/arm/mach-omap2/clock2430_data.c |   48 +++
 arch/arm/mach-omap2/clock3xxx_data.c |   36 +++
 arch/arm/mach-omap2/clock44xx_data.c |   33 +
 4 files changed, 167 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/clock2420_data.c 
b/arch/arm/mach-omap2/clock2420_data.c
index 2926d02..15114f5 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1838,9 +1838,9 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL,   gpt9_ick, gpt9_ick,  CK_242X),
CLK(NULL,   gpt9_fck, gpt9_fck,  CK_242X),
CLK(NULL,   gpt10_ick,gpt10_ick, CK_242X),
-   CLK(NULL,   gpt10_fck,gpt10_fck, CK_242X),
+   CLK(NULL,   gpt_10fck,gpt10_fck, CK_242X),
CLK(NULL,   gpt11_ick,gpt11_ick, CK_242X),
-   CLK(NULL,   gpt11_fck,gpt11_fck, CK_242X),
+   CLK(NULL,   gpt_11fck,gpt11_fck, CK_242X),
CLK(NULL,   gpt12_ick,gpt12_ick, CK_242X),
CLK(NULL,   gpt12_fck,gpt12_fck, CK_242X),
CLK(omap-mcbsp.1, ick,  mcbsp1_ick,CK_242X),
@@ -1898,6 +1898,54 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL,   pka_ick,  pka_ick,   CK_242X),
CLK(NULL,   usb_fck,  usb_fck,   CK_242X),
CLK(musb-hdrc,fck,  osc_ck,CK_242X),
+   CLK(omap_timer.1, fck,  gpt1_fck,  CK_242X),
+   CLK(omap_timer.2, fck,  gpt2_fck,  CK_242X),
+   CLK(omap_timer.3, fck,  gpt3_fck,  CK_242X),
+   CLK(omap_timer.4, fck,  gpt4_fck,  CK_242X),
+   CLK(omap_timer.5, fck,  gpt5_fck,  CK_242X),
+   CLK(omap_timer.6, fck,  gpt6_fck,  CK_242X),
+   CLK(omap_timer.7, fck,  gpt7_fck,  CK_242X),
+   CLK(omap_timer.8, fck,  gpt8_fck,  CK_242X),
+   CLK(omap_timer.9, fck,  gpt9_fck,  CK_242X),
+   CLK(omap_timer.10,fck,  gpt10_fck, CK_242X),
+   CLK(omap_timer.11,fck,  gpt11_fck, CK_242X),
+   CLK(omap_timer.12,fck,  gpt12_fck, CK_242X),
+   CLK(omap_timer.1, 32k_ck,   func_32k_ck,   CK_243X),
+   CLK(omap_timer.2, 32k_ck,   func_32k_ck,   CK_243X),
+   CLK(omap_timer.3, 32k_ck,   func_32k_ck,   CK_243X),
+   CLK(omap_timer.4, 32k_ck,   func_32k_ck,   CK_243X),
+   CLK(omap_timer.5, 32k_ck,   func_32k_ck,   CK_243X),
+   CLK(omap_timer.6, 32k_ck,   func_32k_ck,   CK_243X),
+   CLK(omap_timer.7, 32k_ck,   func_32k_ck,   CK_243X),
+   CLK(omap_timer.8, 32k_ck,   func_32k_ck,   CK_243X),
+   CLK(omap_timer.9, 32k_ck,   func_32k_ck,   CK_243X),
+   CLK(omap_timer.10,32k_ck,   func_32k_ck,   CK_243X),
+   CLK(omap_timer.11,32k_ck,   func_32k_ck,   CK_243X),
+   CLK(omap_timer.12,32k_ck,   func_32k_ck,   CK_243X),
+   CLK(omap_timer.1, sys_ck,   sys_ck,CK_243X),
+   CLK(omap_timer.2, sys_ck,   sys_ck,CK_243X),
+   CLK(omap_timer.3, sys_ck,   sys_ck,CK_243X),
+   CLK(omap_timer.4, sys_ck,   sys_ck,CK_243X),
+   CLK(omap_timer.5, sys_ck,   sys_ck,CK_243X),
+   CLK(omap_timer.6, sys_ck,   sys_ck,CK_243X),
+   CLK(omap_timer.7, sys_ck,   sys_ck,CK_243X),
+   CLK(omap_timer.8, sys_ck,   sys_ck,CK_243X),
+   CLK(omap_timer.9, sys_ck,   sys_ck,CK_243X),
+   CLK(omap_timer.10,sys_ck,   sys_ck,CK_243X),
+   CLK(omap_timer.11,sys_ck,   sys_ck,CK_243X),
+   CLK(omap_timer.12,sys_ck,   sys_ck,CK_243X),
+   CLK(omap_timer.1, alt_ck,   alt_ck,CK_243X),
+   CLK(omap_timer.2, alt_ck,   alt_ck,CK_243X),
+   CLK(omap_timer.3, alt_ck,   alt_ck,CK_243X),
+   CLK(omap_timer.4, alt_ck,   alt_ck,CK_243X),
+   CLK(omap_timer.5, alt_ck,   alt_ck,CK_243X),
+   CLK(omap_timer.6, alt_ck,   alt_ck,CK_243X),
+   CLK(omap_timer.7, alt_ck,   alt_ck,CK_243X),
+   CLK(omap_timer.8, alt_ck,   alt_ck,CK_243X),
+   CLK(omap_timer.9, alt_ck,   alt_ck,CK_243X),
+   CLK(omap_timer.10,alt_ck,   alt_ck,CK_243X),
+   CLK(omap_timer.11,alt_ck,   alt_ck, 

[PATCH v13 02/11] OMAP4: hwmod data: add dmtimer version information

2011-04-16 Thread Tarun Kanti DebBarma
OMAP4 has two groups of timers: version 1 timers are 1, 2, 10,
while the rest of the timers, 3-9, 11 are version 2 timers.
The version information is required by the driver so that they
could be handled correctly by it.

Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com
Acked-by: Cousson, Benoit b-cous...@ti.com
Cc: Cousson, Benoit b-cous...@ti.com
---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |3 +++
 arch/arm/plat-omap/include/plat/dmtimer.h  |4 +++-
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index e2d8c28..a0af525 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -27,6 +27,7 @@
 #include plat/mcspi.h
 #include plat/mcbsp.h
 #include plat/mmc.h
+#include plat/dmtimer.h
 
 #include omap_hwmod_common_data.h
 
@@ -3995,6 +3996,7 @@ static struct omap_hwmod_class_sysconfig 
omap44xx_timer_1ms_sysc = {
 static struct omap_hwmod_class omap44xx_timer_1ms_hwmod_class = {
.name   = timer,
.sysc   = omap44xx_timer_1ms_sysc,
+   .rev= OMAP_TIMER_IP_VERSION_1,
 };
 
 static struct omap_hwmod_class_sysconfig omap44xx_timer_sysc = {
@@ -4010,6 +4012,7 @@ static struct omap_hwmod_class_sysconfig 
omap44xx_timer_sysc = {
 static struct omap_hwmod_class omap44xx_timer_hwmod_class = {
.name   = timer,
.sysc   = omap44xx_timer_sysc,
+   .rev= OMAP_TIMER_IP_VERSION_2,
 };
 
 /* timer1 */
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h 
b/arch/arm/plat-omap/include/plat/dmtimer.h
index 6f4e388..543cec7 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -54,7 +54,9 @@
  * IP revision identifier so that Highlander IP
  * in OMAP4 can be distinguished.
  */
-#define OMAP_TIMER_IP_VERSION_10x1
+#define OMAP_TIMER_IP_VERSION_10x1
+#define OMAP_TIMER_IP_VERSION_20x2
+
 struct omap_dm_timer;
 extern struct omap_dm_timer *gptimer_wakeup;
 struct clk;
-- 
1.6.0.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 05/11] OMAP: dmtimer: platform driver

2011-04-16 Thread Tarun Kanti DebBarma
Add dmtimer platform driver functions which include:
(1) platform driver initialization
(2) driver probe function
(3) driver remove function

Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com
Signed-off-by: Thara Gopinath th...@ti.com
Acked-by: Cousson, Benoit b-cous...@ti.com
---
 arch/arm/plat-omap/dmtimer.c  |  159 +++-
 arch/arm/plat-omap/include/plat/dmtimer.h |   11 ++
 2 files changed, 164 insertions(+), 6 deletions(-)

diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 0f3e9c9..b2398a7 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -35,15 +35,12 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include linux/init.h
-#include linux/spinlock.h
-#include linux/errno.h
-#include linux/list.h
 #include linux/clk.h
 #include linux/delay.h
 #include linux/io.h
-#include linux/module.h
-#include mach/hardware.h
+#include linux/slab.h
+#include linux/err.h
+
 #include plat/dmtimer.h
 #include mach/irqs.h
 
@@ -149,6 +146,7 @@ static const char **dm_source_names;
 static struct clk **dm_source_clocks;
 
 static spinlock_t dm_timer_lock;
+static LIST_HEAD(omap_timer_list);
 
 /*
  * Reads timer registers in posted and non-posted mode. The posted mode bit
@@ -575,6 +573,155 @@ int omap_dm_timers_active(void)
 }
 EXPORT_SYMBOL_GPL(omap_dm_timers_active);
 
+/**
+ * omap_dm_timer_probe - probe function called for every registered device
+ * @pdev:  pointer to current timer platform device
+ *
+ * Called by driver framework at the end of device registration for all
+ * timer devices.
+ */
+static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
+{
+   int ret;
+   unsigned long flags;
+   struct omap_dm_timer *timer;
+   struct resource *mem, *irq, *ioarea;
+   struct dmtimer_platform_data *pdata = pdev-dev.platform_data;
+
+   if (!pdata) {
+   dev_err(pdev-dev, %s: no platform data.\n, __func__);
+   return -ENODEV;
+   }
+
+   irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+   if (unlikely(!irq)) {
+   dev_err(pdev-dev, %s: no IRQ resource.\n, __func__);
+   ret = -ENODEV;
+   goto err_free_pdev;
+   }
+
+   mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (unlikely(!mem)) {
+   dev_err(pdev-dev, %s: no memory resource.\n, __func__);
+   ret = -ENODEV;
+   goto err_free_pdev;
+   }
+
+   ioarea = request_mem_region(mem-start, resource_size(mem),
+   pdev-name);
+   if (!ioarea) {
+   dev_err(pdev-dev, %s: region already claimed.\n, __func__);
+   ret = -EBUSY;
+   goto err_free_pdev;
+   }
+
+   timer = kzalloc(sizeof(struct omap_dm_timer), GFP_KERNEL);
+   if (!timer) {
+   dev_err(pdev-dev, %s: no memory for omap_dm_timer.\n,
+   __func__);
+   ret = -ENOMEM;
+   goto err_release_ioregion;
+   }
+
+   timer-io_base = ioremap(mem-start, resource_size(mem));
+   if (!timer-io_base) {
+   dev_err(pdev-dev, %s: ioremap failed.\n, __func__);
+   ret = -ENOMEM;
+   goto err_free_mem;
+   }
+
+   if (pdata-timer_ip_type == OMAP_TIMER_IP_VERSION_2) {
+   timer-func_offset = VERSION2_TIMER_WAKEUP_EN_REG_OFFSET;
+   timer-intr_offset = VERSION2_TIMER_STAT_REG_OFFSET;
+   } else {
+   timer-func_offset = 0;
+   timer-intr_offset = 0;
+   }
+
+   timer-id = pdev-id;
+   timer-irq = irq-start;
+   timer-pdev = pdev;
+   timer-reserved = 0;
+
+   /* add the timer element to the list */
+   spin_lock_irqsave(dm_timer_lock, flags);
+   list_add_tail(timer-node, omap_timer_list);
+   spin_unlock_irqrestore(dm_timer_lock, flags);
+
+   dev_dbg(pdev-dev, Device Probed.\n);
+
+   return 0;
+
+err_free_mem:
+   kfree(timer);
+
+err_release_ioregion:
+   release_mem_region(mem-start, resource_size(mem));
+
+err_free_pdev:
+   kfree(pdata);
+   platform_device_unregister(pdev);
+
+   return ret;
+}
+
+/**
+ * omap_dm_timer_remove - cleanup a registered timer device
+ * @pdev:  pointer to current timer platform device
+ *
+ * Called by driver framework whenever a timer device is unregistered.
+ * In addition to freeing platform resources it also deletes the timer
+ * entry from the local list.
+ */
+static int __devexit omap_dm_timer_remove(struct platform_device *pdev)
+{
+   struct omap_dm_timer *timer, *tmp;
+   unsigned long flags;
+   int ret = -EINVAL;
+
+   spin_lock_irqsave(dm_timer_lock, flags);
+   list_for_each_entry_safe(timer, tmp, omap_timer_list, node) {
+   if (timer-pdev-id == pdev-id) {
+   kfree(timer-pdev-dev.platform_data);
+   

[PATCH v13 03/11] OMAP1: dmtimer: conversion to platform devices

2011-04-16 Thread Tarun Kanti DebBarma
From: Thara Gopinath th...@ti.com

Convert OMAP1 dmtimers into a platform devices and then registers with
device model framework so that it can be bound to corresponding driver.

Signed-off-by: Thara Gopinath th...@ti.com
Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com
Acked-by: Cousson, Benoit b-cous...@ti.com
---
 arch/arm/mach-omap1/Makefile  |2 +-
 arch/arm/mach-omap1/dmtimer.c |  174 +
 arch/arm/plat-omap/dmtimer.c  |   52 ++---
 arch/arm/plat-omap/include/plat/dmtimer.h |   10 +-
 4 files changed, 190 insertions(+), 48 deletions(-)
 create mode 100644 arch/arm/mach-omap1/dmtimer.c

diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index af98117..a0ae35f 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -4,7 +4,7 @@
 
 # Common support
 obj-y := io.o id.o sram.o time.o irq.o mux.o flash.o serial.o devices.o dma.o
-obj-y += clock.o clock_data.o opp_data.o reset.o
+obj-y += clock.o clock_data.o opp_data.o reset.o dmtimer.o
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
diff --git a/arch/arm/mach-omap1/dmtimer.c b/arch/arm/mach-omap1/dmtimer.c
new file mode 100644
index 000..980b23b
--- /dev/null
+++ b/arch/arm/mach-omap1/dmtimer.c
@@ -0,0 +1,174 @@
+/**
+ * OMAP1 Dual-Mode Timers - platform device registration
+ *
+ * Contains first level initialization routines which internally
+ * generates timer device information and registers with linux
+ * device model. It also has low level function to chnage the timer
+ * input clock source.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Tarun Kanti DebBarma tarun.ka...@ti.com
+ * Thara Gopinath th...@ti.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.
+ *
+ * This program is distributed as is WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include linux/clk.h
+#include linux/io.h
+#include linux/err.h
+#include linux/slab.h
+#include linux/platform_device.h
+
+#include mach/irqs.h
+
+#include plat/dmtimer.h
+
+#define OMAP1610_GPTIMER1_BASE 0xfffb1400
+#define OMAP1610_GPTIMER2_BASE 0xfffb1c00
+#define OMAP1610_GPTIMER3_BASE 0xfffb2400
+#define OMAP1610_GPTIMER4_BASE 0xfffb2c00
+#define OMAP1610_GPTIMER5_BASE 0xfffb3400
+#define OMAP1610_GPTIMER6_BASE 0xfffb3c00
+#define OMAP1610_GPTIMER7_BASE 0xfffb7400
+#define OMAP1610_GPTIMER8_BASE 0xfffbd400
+
+#define OMAP1_DM_TIMER_COUNT   8
+
+static int omap1_dm_timer_set_src(struct platform_device *pdev,
+   int source)
+{
+   int n = (pdev-id - 1)  1;
+   u32 l;
+
+   l = omap_readl(MOD_CONF_CTRL_1)  ~(0x03  n);
+   l |= source  n;
+   omap_writel(l, MOD_CONF_CTRL_1);
+
+   return 0;
+}
+
+
+int __init omap1_dm_timer_init(void)
+{
+   int i;
+   int ret;
+   struct dmtimer_platform_data *pdata;
+   struct platform_device *pdev;
+
+   if (!cpu_is_omap16xx())
+   return 0;
+
+   for (i = 1; i = OMAP1_DM_TIMER_COUNT; i++) {
+   struct resource res[2];
+   u32 base, irq;
+
+   switch (i) {
+   case 1:
+   base = OMAP1610_GPTIMER1_BASE;
+   irq = INT_1610_GPTIMER1;
+   break;
+   case 2:
+   base = OMAP1610_GPTIMER2_BASE;
+   irq = INT_1610_GPTIMER2;
+   break;
+   case 3:
+   base = OMAP1610_GPTIMER3_BASE;
+   irq = INT_1610_GPTIMER3;
+   break;
+   case 4:
+   base = OMAP1610_GPTIMER4_BASE;
+   irq = INT_1610_GPTIMER4;
+   break;
+   case 5:
+   base = OMAP1610_GPTIMER5_BASE;
+   irq = INT_1610_GPTIMER5;
+   break;
+   case 6:
+   base = OMAP1610_GPTIMER6_BASE;
+   irq = INT_1610_GPTIMER6;
+   break;
+   case 7:
+   base = OMAP1610_GPTIMER7_BASE;
+   irq = INT_1610_GPTIMER7;
+   break;
+   case 8:
+   base = OMAP1610_GPTIMER8_BASE;
+   irq = INT_1610_GPTIMER8;
+   break;
+   default:
+   /*
+* not supposed to reach here.
+* this is to remove warning.
+*/
+ 

[PATCH v13 04/11] OMAP2+: dmtimer: convert to platform devices

2011-04-16 Thread Tarun Kanti DebBarma
Add routines to converts dmtimers to platform devices. The device data
is obtained from hwmod database of respective platform and is registered
to device model after successful binding to driver.
In addition, capability attribute of each of the timers is added in
hwmod database.

Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com
Signed-off-by: Thara Gopinath th...@ti.com
Acked-by: Cousson, Benoit b-cous...@ti.com
---
 arch/arm/mach-omap2/omap_hwmod_2420_data.c |   22 
 arch/arm/mach-omap2/omap_hwmod_2430_data.c |   22 
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |   27 +
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |   25 +
 arch/arm/mach-omap2/timer.c|  158 +++-
 arch/arm/plat-omap/dmtimer.c   |   17 ---
 arch/arm/plat-omap/include/plat/dmtimer.h  |   13 ++-
 7 files changed, 265 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c 
b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index 8eb3ce1..1f7cb36 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -358,6 +358,16 @@ static struct omap_hwmod_class omap2420_timer_hwmod_class 
= {
.rev = OMAP_TIMER_IP_VERSION_1,
 };
 
+/* always-on timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
+   .timer_capability   = OMAP_TIMER_ALWON,
+};
+
+/* pwm timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = {
+   .timer_capability   = OMAP_TIMER_HAS_PWM,
+};
+
 /* timer1 */
 static struct omap_hwmod omap2420_timer1_hwmod;
 static struct omap_hwmod_irq_info omap2420_timer1_mpu_irqs[] = {
@@ -402,6 +412,7 @@ static struct omap_hwmod omap2420_timer1_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT1_SHIFT,
},
},
+   .dev_attr   = capability_alwon_dev_attr,
.slaves = omap2420_timer1_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer1_slaves),
.class  = omap2420_timer_hwmod_class,
@@ -452,6 +463,7 @@ static struct omap_hwmod omap2420_timer2_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT,
},
},
+   .dev_attr   = capability_alwon_dev_attr,
.slaves = omap2420_timer2_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer2_slaves),
.class  = omap2420_timer_hwmod_class,
@@ -502,6 +514,7 @@ static struct omap_hwmod omap2420_timer3_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT3_SHIFT,
},
},
+   .dev_attr   = capability_alwon_dev_attr,
.slaves = omap2420_timer3_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer3_slaves),
.class  = omap2420_timer_hwmod_class,
@@ -552,6 +565,7 @@ static struct omap_hwmod omap2420_timer4_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT4_SHIFT,
},
},
+   .dev_attr   = capability_alwon_dev_attr,
.slaves = omap2420_timer4_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer4_slaves),
.class  = omap2420_timer_hwmod_class,
@@ -602,6 +616,7 @@ static struct omap_hwmod omap2420_timer5_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT,
},
},
+   .dev_attr   = capability_alwon_dev_attr,
.slaves = omap2420_timer5_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer5_slaves),
.class  = omap2420_timer_hwmod_class,
@@ -653,6 +668,7 @@ static struct omap_hwmod omap2420_timer6_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT,
},
},
+   .dev_attr   = capability_alwon_dev_attr,
.slaves = omap2420_timer6_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer6_slaves),
.class  = omap2420_timer_hwmod_class,
@@ -703,6 +719,7 @@ static struct omap_hwmod omap2420_timer7_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT,
},
},
+   .dev_attr   = capability_alwon_dev_attr,
.slaves = omap2420_timer7_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer7_slaves),
.class  = omap2420_timer_hwmod_class,
@@ -753,6 +770,7 @@ static struct omap_hwmod omap2420_timer8_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT,
},
},
+   .dev_attr   = capability_alwon_dev_attr,
.slaves = omap2420_timer8_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer8_slaves),
.class  = omap2420_timer_hwmod_class,
@@ -803,6 +821,7 @@ static struct omap_hwmod omap2420_timer9_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT9_SHIFT,
},
},
+   

[PATCH v13 07/11] OMAP: dmtimer: pm_runtime support

2011-04-16 Thread Tarun Kanti DebBarma
Add pm_runtime feature to dmtimer whereby _get_sync() is called within
omap_dm_timer_enable(), _put_sync() is called in omap_dm_timer_disable().

Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com
[p-bas...@ti.com: added pm_runtime logic in probe()]
Signed-off-by: Partha Basak p-bas...@ti.com
Reviewed-by: Varadarajan, Charulatha ch...@ti.com
Acked-by: Cousson, Benoit b-cous...@ti.com
---
 arch/arm/plat-omap/dmtimer.c |   11 +++
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 8cd5cf6..b61edc2 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -38,6 +38,7 @@
 #include linux/clk.h
 #include linux/io.h
 #include linux/slab.h
+#include linux/pm_runtime.h
 #include linux/err.h
 
 #include plat/dmtimer.h
@@ -218,8 +219,7 @@ void omap_dm_timer_enable(struct omap_dm_timer *timer)
if (timer-enabled)
return;
 
-   clk_enable(timer-fclk);
-   clk_enable(timer-iclk);
+   pm_runtime_get_sync(timer-pdev-dev);
 
timer-enabled = 1;
 }
@@ -230,8 +230,7 @@ void omap_dm_timer_disable(struct omap_dm_timer *timer)
if (!timer-enabled)
return;
 
-   clk_disable(timer-fclk);
-   clk_disable(timer-iclk);
+   pm_runtime_put_sync(timer-pdev-dev);
 
timer-enabled = 0;
 }
@@ -561,6 +560,10 @@ static int __devinit omap_dm_timer_probe(struct 
platform_device *pdev)
timer-pdev = pdev;
timer-reserved = 0;
 
+/* Skip pm_runtime_enable for OMAP1 */
+   if (!pdata-needs_manual_reset)
+   pm_runtime_enable(pdev-dev);
+
/* add the timer element to the list */
spin_lock_irqsave(dm_timer_lock, flags);
list_add_tail(timer-node, omap_timer_list);
-- 
1.6.0.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 06/11] dmtimer: switch-over to platform device driver

2011-04-16 Thread Tarun Kanti DebBarma
Register timer devices by going through hwmod database using
hwmod API. The driver probes each of the registered devices.
Functionality which are already performed by hwmod framework
are removed from timer code. New set of timers present on
OMAP4 are now supported.

Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com
Acked-by: Cousson, Benoit b-cous...@ti.com
---
 arch/arm/mach-omap2/timer.c   |   44 +++-
 arch/arm/plat-omap/dmtimer.c  |  377 +
 arch/arm/plat-omap/include/plat/dmtimer.h |   74 --
 3 files changed, 205 insertions(+), 290 deletions(-)

diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 1c80337..b7862ca 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -80,7 +80,8 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void 
*dev_id)
 {
struct clock_event_device *evt = clockevent_gpt;
 
-   __omap_dm_timer_write_status(clkev.io_base, OMAP_TIMER_INT_OVERFLOW);
+   __omap_dm_timer_write_status(clkev.io_base, OMAP_TIMER_INT_OVERFLOW,
+   0, clkev.intr_offset, clkev.func_offset);
 
evt-event_handler(evt);
return IRQ_HANDLED;
@@ -96,7 +97,7 @@ static int omap2_gp_timer_set_next_event(unsigned long cycles,
 struct clock_event_device *evt)
 {
__omap_dm_timer_load_start(clkev.io_base, OMAP_TIMER_CTRL_ST,
-   0x - cycles, 1);
+   0x - cycles, 1, clkev.func_offset);
 
return 0;
 }
@@ -105,8 +106,10 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode 
mode,
struct clock_event_device *evt)
 {
u32 period;
+   unsigned long rate = clk_get_rate(clkev.fclk) + 1;
 
-   omap_dm_timer_stop(clkev);
+   __omap_dm_timer_stop(clkev.io_base, rate, 0, true, clkev.intr_offset,
+   clkev.func_offset);
 
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
@@ -131,7 +134,7 @@ static struct clock_event_device clockevent_gpt = {
.set_mode   = omap2_gp_timer_set_mode,
 };
 
-int __omap_dm_timer_set_source(struct clk *timer_fck, struct clk *parent)
+static int __omap_dm_timer_set_source(struct clk *timer_fck, struct clk 
*parent)
 {
int ret;
 
@@ -204,6 +207,7 @@ static int __init omap_dm_timer_init_one(struct 
omap_dm_timer *timer,
}
}
__omap_dm_timer_reset(timer, 1, 1);
+   __omap_dm_timer_set_posted(timer-io_base, timer-func_offset);
 
timer-rate = clk_get_rate(timer-fclk);
 
@@ -223,7 +227,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
omap2_gp_timer_irq.dev_id = (void *)clkev;
setup_irq(clkev.irq, omap2_gp_timer_irq);
 
-   __omap_dm_timer_int_enable(clkev.io_base, OMAP_TIMER_INT_OVERFLOW);
+   __omap_dm_timer_int_enable(clkev.io_base, OMAP_TIMER_INT_OVERFLOW,
+   0, clkev.intr_offset, clkev.func_offset);
 
clockevent_gpt.mult = div_sc(clkev.rate, NSEC_PER_SEC,
 clockevent_gpt.shift);
@@ -264,7 +269,8 @@ static struct omap_dm_timer clksrc;
 static DEFINE_CLOCK_DATA(cd);
 static cycle_t clocksource_read_cycles(struct clocksource *cs)
 {
-   return (cycle_t)__omap_dm_timer_read_counter(clksrc.io_base, 1);
+   return (cycle_t)__omap_dm_timer_read_counter(clksrc.io_base, 1,
+   clksrc.func_offset);
 }
 
 static struct clocksource clocksource_gpt = {
@@ -279,7 +285,8 @@ static void notrace dmtimer_update_sched_clock(void)
 {
u32 cyc;
 
-   cyc = __omap_dm_timer_read_counter(clksrc.io_base, 1);
+   cyc = __omap_dm_timer_read_counter(clksrc.io_base, 1,
+   clksrc.func_offset);
 
update_sched_clock(cd, cyc, (u32)~0);
 }
@@ -289,7 +296,8 @@ unsigned long long notrace sched_clock(void)
u32 cyc = 0;
 
if (clksrc.reserved)
-   cyc = __omap_dm_timer_read_counter(clksrc.io_base, 1);
+   cyc = __omap_dm_timer_read_counter(clksrc.io_base, 1,
+   clksrc.func_offset);
 
return cyc_to_sched_clock(cd, cyc, (u32)~0);
 }
@@ -515,3 +523,23 @@ static int __init omap_timer_init(struct omap_hwmod *oh, 
void *unused)
 
return ret;
 }
+
+/**
+ * omap2_dm_timer_init - top level regular device initialization
+ *
+ * Uses dedicated hwmod api to parse through hwmod database for
+ * given class name and then build and register the timer device.
+ */
+static int __init omap2_dm_timer_init(void)
+{
+   int ret;
+
+   ret = omap_hwmod_for_each_by_class(timer, omap_timer_init, NULL);
+   if (unlikely(ret)) {
+   pr_err(%s: device registration failed.\n, __func__);
+   return -EINVAL;
+   }
+
+   return 

[PATCH v13 10/11] OMAP: dmtimer: mark clocksource and clockevent timers reserved

2011-04-16 Thread Tarun Kanti DebBarma
In driver probe use sys_timer_reserved to identify which all timers
have already been used for clocksource and clockevent. Mark all those
timers as reserved so that no one else can use them.

Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com
---
 arch/arm/plat-omap/dmtimer.c |8 +++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index e15b3a8..8b6fd22 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -554,7 +554,13 @@ static int __devinit omap_dm_timer_probe(struct 
platform_device *pdev)
timer-id = pdev-id;
timer-irq = irq-start;
timer-pdev = pdev;
-   timer-reserved = 0;
+#if defined(CONFIG_ARCH_OMAP2)
+   /* Mark clocksource and clockevent timers as reserved */
+   if ((sys_timer_reserved  (pdev-id - 1))  0x1)
+   timer-reserved = 1;
+   else
+#endif
+   timer-reserved = 0;
 
 /* Skip pm_runtime_enable for OMAP1 */
if (!pdata-needs_manual_reset)
-- 
1.6.0.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 08/11] OMAP: dmtimer: add timeout to low-level routines

2011-04-16 Thread Tarun Kanti DebBarma
The low-level read and write access routines wait on write-pending register
in posted mode to make sure that previous write is complete on respective
registers. This waiting is done in an infinite while loop. Now it is being
modified to use timeout instead.

Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com
Reviewed-by: Varadarajan, Charulatha ch...@ti.com
Acked-by: Cousson, Benoit b-cous...@ti.com
---
 arch/arm/plat-omap/include/plat/dmtimer.h |   33 
 1 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h 
b/arch/arm/plat-omap/include/plat/dmtimer.h
index 53fd69b..b1c8091 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -37,6 +37,7 @@
 
 #include linux/platform_device.h
 #include linux/delay.h
+#include plat/common.h
 
 /* clock sources */
 #define OMAP_TIMER_SRC_SYS_CLK 0x00
@@ -229,6 +230,8 @@ int omap_dm_timers_active(void);
 #define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \
(_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR  WPSHIFT))
 
+#define MAX_WRITE_PEND_WAIT1 /* 10ms timeout delay */
+
 struct omap_dm_timer {
unsigned long phys_base;
int id;
@@ -254,11 +257,16 @@ void __omap_dm_timer_reset(struct omap_dm_timer *timer, 
int autoidle,
 static inline u32
 __omap_dm_timer_read(void __iomem *base, u32 reg, int posted, u8 func_offset)
 {
-   if (posted)
-   while (__raw_readl(base +
-   ((OMAP_TIMER_WRITE_PEND_REG + func_offset)  0xff))
-(reg  WPSHIFT))
-   cpu_relax();
+   int i = 0;
+
+   if (posted) {
+   omap_test_timeout(!(__raw_readl(base +
+   ((OMAP_TIMER_WRITE_PEND_REG + func_offset)  0xff)) 
+   (reg  WPSHIFT)), MAX_WRITE_PEND_WAIT, i);
+
+   if (WARN_ON_ONCE(i == MAX_WRITE_PEND_WAIT))
+   pr_err(read timeout.\n);
+   }
 
return __raw_readl(base + (reg  0xff));
 }
@@ -266,11 +274,16 @@ __omap_dm_timer_read(void __iomem *base, u32 reg, int 
posted, u8 func_offset)
 static inline void __omap_dm_timer_write(void __iomem *base, u32 reg, u32 val,
int posted, u8 func_offset)
 {
-   if (posted)
-   while (__raw_readl(base +
-   ((OMAP_TIMER_WRITE_PEND_REG + func_offset)  0xff))
-(reg  WPSHIFT))
-   cpu_relax();
+   int i = 0;
+
+   if (posted) {
+   omap_test_timeout(!(__raw_readl(base +
+   ((OMAP_TIMER_WRITE_PEND_REG + func_offset)  0xff)) 
+   (reg  WPSHIFT)), MAX_WRITE_PEND_WAIT, i);
+
+   if (WARN_ON(i == MAX_WRITE_PEND_WAIT))
+   pr_err(write timeout.\n);
+   }
 
__raw_writel(val, base + (reg  0xff));
 }
-- 
1.6.0.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 09/11] OMAP: dmtimer: use mutex instead of spinlock

2011-04-16 Thread Tarun Kanti DebBarma
Since the spinlock is not used in any interrupt context we can
replace it with mutex instead.

Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com
---
 arch/arm/plat-omap/dmtimer.c |   27 +++
 1 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index b61edc2..0716fdb 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -44,7 +44,7 @@
 #include plat/dmtimer.h
 
 static LIST_HEAD(omap_timer_list);
-static DEFINE_SPINLOCK(dm_timer_lock);
+static DEFINE_MUTEX(dm_timer_mutex);
 
 /**
  * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
@@ -157,9 +157,8 @@ void omap_dm_timer_prepare(struct omap_dm_timer *timer)
 struct omap_dm_timer *omap_dm_timer_request(void)
 {
struct omap_dm_timer *timer = NULL, *t;
-   unsigned long flags;
 
-   spin_lock_irqsave(dm_timer_lock, flags);
+   mutex_lock(dm_timer_mutex);
list_for_each_entry(t, omap_timer_list, node) {
if (t-reserved)
continue;
@@ -168,7 +167,7 @@ struct omap_dm_timer *omap_dm_timer_request(void)
timer-reserved = 1;
break;
}
-   spin_unlock_irqrestore(dm_timer_lock, flags);
+   mutex_unlock(dm_timer_mutex);
 
if (timer)
omap_dm_timer_prepare(timer);
@@ -182,9 +181,8 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_request);
 struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 {
struct omap_dm_timer *timer = NULL, *t;
-   unsigned long flags;
 
-   spin_lock_irqsave(dm_timer_lock, flags);
+   mutex_lock(dm_timer_mutex);
list_for_each_entry(t, omap_timer_list, node) {
if (t-pdev-id == id  !t-reserved) {
timer = t;
@@ -192,7 +190,7 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
break;
}
}
-   spin_unlock_irqrestore(dm_timer_lock, flags);
+   mutex_unlock(dm_timer_mutex);
 
if (timer)
omap_dm_timer_prepare(timer);
@@ -252,14 +250,13 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 {
int i = 0;
struct omap_dm_timer *timer = NULL;
-   unsigned long flags;
 
/* If ARMXOR cannot be idled this function call is unnecessary */
if (!(inputmask  (1  1)))
return inputmask;
 
/* If any active timer is using ARMXOR return modified mask */
-   spin_lock_irqsave(dm_timer_lock, flags);
+   mutex_lock(dm_timer_mutex);
list_for_each_entry(timer, omap_timer_list, node) {
 
u32 l;
@@ -273,7 +270,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
}
i++;
}
-   spin_unlock_irqrestore(dm_timer_lock, flags);
+   mutex_unlock(dm_timer_mutex);
 
return inputmask;
 }
@@ -500,7 +497,6 @@ EXPORT_SYMBOL_GPL(omap_dm_timers_active);
 static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
 {
int ret;
-   unsigned long flags;
struct omap_dm_timer *timer;
struct resource *mem, *irq, *ioarea;
struct dmtimer_platform_data *pdata = pdev-dev.platform_data;
@@ -565,9 +561,9 @@ static int __devinit omap_dm_timer_probe(struct 
platform_device *pdev)
pm_runtime_enable(pdev-dev);
 
/* add the timer element to the list */
-   spin_lock_irqsave(dm_timer_lock, flags);
+   mutex_lock(dm_timer_mutex);
list_add_tail(timer-node, omap_timer_list);
-   spin_unlock_irqrestore(dm_timer_lock, flags);
+   mutex_unlock(dm_timer_mutex);
 
dev_dbg(pdev-dev, Device Probed.\n);
 
@@ -597,10 +593,9 @@ err_free_pdev:
 static int __devexit omap_dm_timer_remove(struct platform_device *pdev)
 {
struct omap_dm_timer *timer, *tmp;
-   unsigned long flags;
int ret = -EINVAL;
 
-   spin_lock_irqsave(dm_timer_lock, flags);
+   mutex_lock(dm_timer_mutex);
list_for_each_entry_safe(timer, tmp, omap_timer_list, node) {
if (timer-pdev-id == pdev-id) {
kfree(timer-pdev-dev.platform_data);
@@ -611,7 +606,7 @@ static int __devexit omap_dm_timer_remove(struct 
platform_device *pdev)
break;
}
}
-   spin_unlock_irqrestore(dm_timer_lock, flags);
+   mutex_unlock(dm_timer_mutex);
 
return ret;
 }
-- 
1.6.0.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v13 11/11] OMAP: dmtimer: convert to a driver

2011-04-16 Thread Tarun Kanti DebBarma
Make plat-omap/dmtimer.c a normal driver. It is moved to drivers/misc
as timer-omap.c and the corresponding header file has been moved to
include/linux as timer-omap.h. Files which included plat/dmtimer.h
are changed to include linux/timer-omap.h now.

Signed-off-by: Tarun Kanti DebBarma tarun.ka...@ti.com
---
 arch/arm/mach-omap1/dmtimer.c  |3 +-
 arch/arm/mach-omap1/pm.c   |2 +-
 arch/arm/mach-omap1/timer32k.c |2 +-
 arch/arm/mach-omap2/omap_hwmod_2420_data.c |3 +-
 arch/arm/mach-omap2/omap_hwmod_2430_data.c |3 +-
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |3 +-
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |2 +-
 arch/arm/mach-omap2/pm-debug.c |2 +-
 arch/arm/mach-omap2/timer.c|2 +-
 arch/arm/plat-omap/Makefile|1 -
 drivers/misc/Makefile  |1 +
 drivers/misc/timer-omap.c  |  643 
 drivers/tty/serial/omap-serial.c   |2 +-
 include/linux/timer-omap.h |  351 +++
 14 files changed, 1008 insertions(+), 12 deletions(-)
 create mode 100644 drivers/misc/timer-omap.c
 create mode 100644 include/linux/timer-omap.h

diff --git a/arch/arm/mach-omap1/dmtimer.c b/arch/arm/mach-omap1/dmtimer.c
index 980b23b..3a0cece 100644
--- a/arch/arm/mach-omap1/dmtimer.c
+++ b/arch/arm/mach-omap1/dmtimer.c
@@ -25,11 +25,10 @@
 #include linux/err.h
 #include linux/slab.h
 #include linux/platform_device.h
+#include linux/timer-omap.h
 
 #include mach/irqs.h
 
-#include plat/dmtimer.h
-
 #define OMAP1610_GPTIMER1_BASE 0xfffb1400
 #define OMAP1610_GPTIMER2_BASE 0xfffb1c00
 #define OMAP1610_GPTIMER3_BASE 0xfffb2400
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index 98ba978..4344a70 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -42,6 +42,7 @@
 #include linux/sysfs.h
 #include linux/module.h
 #include linux/io.h
+#include linux/timer-omap.h
 
 #include asm/irq.h
 #include asm/atomic.h
@@ -55,7 +56,6 @@
 #include plat/tc.h
 #include plat/mux.h
 #include plat/dma.h
-#include plat/dmtimer.h
 
 #include pm.h
 
diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
index 96604a5..83b4094 100644
--- a/arch/arm/mach-omap1/timer32k.c
+++ b/arch/arm/mach-omap1/timer32k.c
@@ -45,6 +45,7 @@
 #include linux/clocksource.h
 #include linux/clockchips.h
 #include linux/io.h
+#include linux/timer-omap.h
 
 #include asm/system.h
 #include mach/hardware.h
@@ -53,7 +54,6 @@
 #include asm/mach/irq.h
 #include asm/mach/time.h
 #include plat/common.h
-#include plat/dmtimer.h
 
 /*
  * ---
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c 
b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index 1f7cb36..fe080f4 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -11,6 +11,8 @@
  * XXX handle crossbar/shared link difference for L3?
  * XXX these should be marked initdata for multi-OMAP kernels
  */
+#include linux/timer-omap.h
+
 #include plat/omap_hwmod.h
 #include mach/irqs.h
 #include plat/cpu.h
@@ -19,7 +21,6 @@
 #include plat/i2c.h
 #include plat/gpio.h
 #include plat/mcspi.h
-#include plat/dmtimer.h
 #include plat/l3_2xxx.h
 #include plat/l4_2xxx.h
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c 
b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index d7c6487..85dec8a 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -11,6 +11,8 @@
  * XXX handle crossbar/shared link difference for L3?
  * XXX these should be marked initdata for multi-OMAP kernels
  */
+#include linux/timer-omap.h
+
 #include plat/omap_hwmod.h
 #include mach/irqs.h
 #include plat/cpu.h
@@ -20,7 +22,6 @@
 #include plat/gpio.h
 #include plat/mcbsp.h
 #include plat/mcspi.h
-#include plat/dmtimer.h
 #include plat/mmc.h
 #include plat/l3_2xxx.h
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 7fb2ecc..2649ed8 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -13,6 +13,8 @@
  *
  * XXX these should be marked initdata for multi-OMAP kernels
  */
+#include linux/timer-omap.h
+
 #include plat/omap_hwmod.h
 #include mach/irqs.h
 #include plat/cpu.h
@@ -25,7 +27,6 @@
 #include plat/mmc.h
 #include plat/mcbsp.h
 #include plat/mcspi.h
-#include plat/dmtimer.h
 
 #include omap_hwmod_common_data.h
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index ab6967b..760d280 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -19,6 +19,7 @@
  */
 
 #include linux/io.h
+#include linux/timer-omap.h
 
 #include plat/omap_hwmod.h
 #include plat/cpu.h
@@ -27,7 +28,6 @@
 #include 

Re: [PATCH 1/2 v2] OMAP2/3: hwmod: fix the i2c-reset timeout during bootup

2011-04-16 Thread Kevin Hilman
On Mon, 2011-04-11 at 18:41 +0530, Avinash.H.M. wrote:
+ oh-_sysc_cache = v;
+ omap_hwmod_write(v, oh, oh-class-sysc-sysc_offs);
  
   Direct SYSCONFIG access isn't right here.   This should go through
   omap_hwmod.
  
   What is probably needed is exposing _ocp_softreset to device code
   via something like omap_hwmod_ocp_softreset() and calling that here.
  
 
 Hi Kevin , 
 
 Looking more closely, i realised that, the sequence of _ocp_softreset
 doesn't work for I2C. It has a special programming sequence which needs
 to be followed to reset the IP. That was the reason, we created
 omap_i2c_reset.  So i feel we need not expose _ocp_softreset.
 
 Since, the problem here is accessing the SYSCONFIG here, instead, what i
 can do is, something like below.
 
   omap_hwmod_softreset(struct omap_hwmod *oh)
   {
 
   v = oh-_sysc_cache;
   v |= (0x1  oh-class-sysc-sysc_fields-srst_shift);
 
   oh-_sysc_cache = v;
   omap_hwmod_write(v, oh, oh-class-sysc-sysc_offs);
 
   }
 
 And then call this in omap_i2c_reset. Is this OK ?

Yes, sounds reasonable.

Please be sure to describe the reasoning above in the changelog as well.

Thanks,

Kevin


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/2] OMAP: convert boards that use SMSC911x to use gpmc-smsc911x

2011-04-16 Thread Mike Rapoport
There are several OMAP boards that use SMSC911x Ethernet controller. Convert 
them all to use gpmc-smsc911x for device registration.

Mike Rapoport (2):
  OMAP: gpmc-smsc911x: always set irq flags to IORESOURCE_IRQ_LOWLEVEL
  OMAP: convert boards that use SMSC911x to use gpmc-smsc911x

 arch/arm/mach-omap2/board-cm-t35.c  |   84 +++--
 arch/arm/mach-omap2/board-igep0020.c|   53 ++---
 arch/arm/mach-omap2/board-ldp.c |   65 ++--
 arch/arm/mach-omap2/board-omap3evm.c|   71 +++---
 arch/arm/mach-omap2/board-omap3logic.c  |1 -
 arch/arm/mach-omap2/board-omap3stalker.c|   48 ++--
 arch/arm/mach-omap2/board-overo.c   |  108 ---
 arch/arm/mach-omap2/board-zoom-debugboard.c |   56 ++
 arch/arm/mach-omap2/gpmc-smsc911x.c |7 +-
 9 files changed, 70 insertions(+), 423 deletions(-)

-- 
1.7.3.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] OMAP: gpmc-smsc911x: always set irq flags to IORESOURCE_IRQ_LOWLEVEL

2011-04-16 Thread Mike Rapoport
SMSC911x devices attached to OMAP GPMC always use low level irqs.
Setting the appropriate flag in the irq resourse strucure allows using
.flags field in the omap_smsc911x_platform_data for driver specific
flags

Signed-off-by: Mike Rapoport m...@compulab.co.il
---
 arch/arm/mach-omap2/board-omap3logic.c |1 -
 arch/arm/mach-omap2/gpmc-smsc911x.c|7 ---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3logic.c 
b/arch/arm/mach-omap2/board-omap3logic.c
index b726943..a49e6cf 100644
--- a/arch/arm/mach-omap2/board-omap3logic.c
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -147,7 +147,6 @@ static struct omap_smsc911x_platform_data __initdata 
board_smsc911x_data = {
.cs = OMAP3LOGIC_SMSC911X_CS,
.gpio_irq   = -EINVAL,
.gpio_reset = -EINVAL,
-   .flags  = IORESOURCE_IRQ_LOWLEVEL,
 };
 
 /* TODO/FIXME (comment by Peter Barada, LogicPD):
diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c 
b/arch/arm/mach-omap2/gpmc-smsc911x.c
index 703f150..b331f3c 100644
--- a/arch/arm/mach-omap2/gpmc-smsc911x.c
+++ b/arch/arm/mach-omap2/gpmc-smsc911x.c
@@ -30,7 +30,7 @@ static struct resource gpmc_smsc911x_resources[] = {
.flags  = IORESOURCE_MEM,
},
[1] = {
-   .flags  = IORESOURCE_IRQ,
+   .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
},
 };
 
@@ -79,8 +79,6 @@ void __init gpmc_smsc911x_init(struct 
omap_smsc911x_platform_data *board_data)
 
gpio_direction_input(gpmc_cfg-gpio_irq);
gpmc_smsc911x_resources[1].start = gpio_to_irq(gpmc_cfg-gpio_irq);
-   gpmc_smsc911x_resources[1].flags |=
-   (gpmc_cfg-flags  IRQF_TRIGGER_MASK);
 
if (gpio_is_valid(gpmc_cfg-gpio_reset)) {
ret = gpio_request(gpmc_cfg-gpio_reset, smsc911x reset);
@@ -96,6 +94,9 @@ void __init gpmc_smsc911x_init(struct 
omap_smsc911x_platform_data *board_data)
gpio_set_value(gpmc_cfg-gpio_reset, 1);
}
 
+   if (gpmc_cfg-flags)
+   gpmc_smsc911x_config.flags = gpmc_cfg-flags;
+
if (platform_device_register(gpmc_smsc911x_device)  0) {
printk(KERN_ERR Unable to register smsc911x device\n);
gpio_free(gpmc_cfg-gpio_reset);
-- 
1.7.3.1

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] OMAP: convert boards that use SMSC911x to use gpmc-smsc911x

2011-04-16 Thread Mike Rapoport
Signed-off-by: Mike Rapoport m...@compulab.co.il
---
 arch/arm/mach-omap2/board-cm-t35.c  |   84 +++--
 arch/arm/mach-omap2/board-igep0020.c|   53 ++---
 arch/arm/mach-omap2/board-ldp.c |   65 ++--
 arch/arm/mach-omap2/board-omap3evm.c|   71 +++---
 arch/arm/mach-omap2/board-omap3stalker.c|   48 ++--
 arch/arm/mach-omap2/board-overo.c   |  108 ---
 arch/arm/mach-omap2/board-zoom-debugboard.c |   56 ++
 7 files changed, 66 insertions(+), 419 deletions(-)

diff --git a/arch/arm/mach-omap2/board-cm-t35.c 
b/arch/arm/mach-omap2/board-cm-t35.c
index 02a12b4..b5772c1 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -66,86 +66,26 @@
 
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 #include linux/smsc911x.h
+#include plat/gpmc-smsc911x.h
 
-static struct smsc911x_platform_config cm_t35_smsc911x_config = {
-   .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-   .irq_type   = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+static struct omap_smsc911x_platform_data cm_t35_smsc911x_cfg = {
+   .cs = CM_T35_SMSC911X_CS,
+   .gpio_irq   = CM_T35_SMSC911X_GPIO,
+   .gpio_reset = -EINVAL,
.flags  = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
-   .phy_interface  = PHY_INTERFACE_MODE_MII,
 };
 
-static struct resource cm_t35_smsc911x_resources[] = {
-   {
-   .flags  = IORESOURCE_MEM,
-   },
-   {
-   .start  = OMAP_GPIO_IRQ(CM_T35_SMSC911X_GPIO),
-   .end= OMAP_GPIO_IRQ(CM_T35_SMSC911X_GPIO),
-   .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-   },
-};
-
-static struct platform_device cm_t35_smsc911x_device = {
-   .name   = smsc911x,
-   .id = 0,
-   .num_resources  = ARRAY_SIZE(cm_t35_smsc911x_resources),
-   .resource   = cm_t35_smsc911x_resources,
-   .dev= {
-   .platform_data = cm_t35_smsc911x_config,
-   },
-};
-
-static struct resource sb_t35_smsc911x_resources[] = {
-   {
-   .flags  = IORESOURCE_MEM,
-   },
-   {
-   .start  = OMAP_GPIO_IRQ(SB_T35_SMSC911X_GPIO),
-   .end= OMAP_GPIO_IRQ(SB_T35_SMSC911X_GPIO),
-   .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-   },
-};
-
-static struct platform_device sb_t35_smsc911x_device = {
-   .name   = smsc911x,
-   .id = 1,
-   .num_resources  = ARRAY_SIZE(sb_t35_smsc911x_resources),
-   .resource   = sb_t35_smsc911x_resources,
-   .dev= {
-   .platform_data = cm_t35_smsc911x_config,
-   },
+static struct omap_smsc911x_platform_data sb_t35_smsc911x_cfg = {
+   .cs = SB_T35_SMSC911X_CS,
+   .gpio_irq   = SB_T35_SMSC911X_GPIO,
+   .gpio_reset = -EINVAL,
+   .flags  = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
 };
 
-static void __init cm_t35_init_smsc911x(struct platform_device *dev,
-   int cs, int irq_gpio)
-{
-   unsigned long cs_mem_base;
-
-   if (gpmc_cs_request(cs, SZ_16M, cs_mem_base)  0) {
-   pr_err(CM-T35: Failed request for GPMC mem for smsc911x\n);
-   return;
-   }
-
-   dev-resource[0].start = cs_mem_base + 0x0;
-   dev-resource[0].end   = cs_mem_base + 0xff;
-
-   if ((gpio_request(irq_gpio, ETH IRQ) == 0) 
-   (gpio_direction_input(irq_gpio) == 0)) {
-   gpio_export(irq_gpio, 0);
-   } else {
-   pr_err(CM-T35: could not obtain gpio for SMSC911X IRQ\n);
-   return;
-   }
-
-   platform_device_register(dev);
-}
-
 static void __init cm_t35_init_ethernet(void)
 {
-   cm_t35_init_smsc911x(cm_t35_smsc911x_device,
-CM_T35_SMSC911X_CS, CM_T35_SMSC911X_GPIO);
-   cm_t35_init_smsc911x(sb_t35_smsc911x_device,
-SB_T35_SMSC911X_CS, SB_T35_SMSC911X_GPIO);
+   gpmc_smsc911x_init(cm_t35_smsc911x_cfg);
+   gpmc_smsc911x_init(sb_t35_smsc911x_cfg);
 }
 #else
 static inline void __init cm_t35_init_ethernet(void) { return; }
diff --git a/arch/arm/mach-omap2/board-igep0020.c 
b/arch/arm/mach-omap2/board-igep0020.c
index 5f8a2fd..bb60414 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -192,57 +192,18 @@ static void __init igep2_flash_init(void) {}
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 
 #include linux/smsc911x.h
+#include plat/gpmc-smsc911x.h
 
-static struct smsc911x_platform_config igep2_smsc911x_config = {
-   .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-   .irq_type   = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
-   .flags  = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS  ,
-