Re: [RFC PATCH] Consolidate SRAM support
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 , -