* [PATCH 1/6] i2c-pxa: move i2c_pxa_remove to __devexit instead of just __exit
From: Uwe Kleine-König @ 2011-01-05 8:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294193110-23958-1-git-send-email-dbaryshkov@gmail.com>
a bit of explanation would be nice here. Something like:
Subject: i2c-pxa: make sure the remove callback is called on unbind
When a "pxa2xx-i2c" device was unbound (e.g. via sysfs) the remove
callback was not called because it was discarded after boot or module
load time. Because of that the resources allocated in probe were not
freed and so a rebind was impossible.
Fix that by moving the remove callback to .devexit.text.
This way everyone can understand that a real bug is fixed here.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH 2/5] omap2plus: prm: Trvial build break fix for undefined reference to 'omap2_prm_read_mod_reg'
From: Santosh Shilimkar @ 2011-01-05 8:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87d3oc42cn.fsf@ti.com>
> -----Original Message-----
> From: Kevin Hilman [mailto:khilman at ti.com]
> Sent: Wednesday, January 05, 2011 6:02 AM
> To: Santosh Shilimkar
> Cc: Paul Walmsley; linux-omap at vger.kernel.org; tony at atomide.com;
> linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH 2/5] omap2plus: prm: Trvial build break fix for
> undefined reference to 'omap2_prm_read_mod_reg'
>
> Santosh Shilimkar <santosh.shilimkar@ti.com> writes:
>
> >> -----Original Message-----
> >> From: Paul Walmsley [mailto:paul at pwsan.com]
> >> Sent: Wednesday, January 05, 2011 12:11 AM
> >> To: Santosh Shilimkar
> >> Cc: linux-omap at vger.kernel.org; khilman at ti.com; tony at atomide.com;
> >> linux-arm-kernel at lists.infradead.org
> >> Subject: Re: [PATCH 2/5] omap2plus: prm: Trvial build break fix
> for
> >> undefined reference to 'omap2_prm_read_mod_reg'
> >>
> >> Hi Santosh,
> >>
> >> On Tue, 4 Jan 2011, Santosh Shilimkar wrote:
> >>
> >> > omap2plus_defocnfig build breaks when customised with only
> >> ARCH_OMAP4
> >> > selected. This is because common files make references to the
> >> functions
> >> > which are defined only for omap2xxx and omap3xxx.
> >> >
> >> > LD .tmp_vmlinux1
> >> > arch/arm/mach-omap2/built-in.o: In function
> `pm_dbg_regset_store':
> >> > arch/arm/mach-omap2/pm-debug.c:335: undefined reference to
> >> `omap2_prm_read_mod_reg'
> >> > arch/arm/mach-omap2/built-in.o: In function `omap2_pm_dump':
> >> > arch/arm/mach-omap2/pm-debug.c:121: undefined reference to
> >> `omap2_prm_read_mod_reg'
> >> > arch/arm/mach-omap2/pm-debug.c:123: undefined reference to
> >> `omap2_prm_read_mod_reg'
> >> > arch/arm/mach-omap2/pm-debug.c:124: undefined reference to
> >> `omap2_prm_read_mod_reg'
> >> > arch/arm/mach-omap2/pm-debug.c:125: undefined reference to
> >> `omap2_prm_read_mod_reg'
> >> > arch/arm/mach-omap2/built-in.o: In function
> >> `omap_prcm_arch_reset':
> >> > arch/arm/mach-omap2/prcm.c:106: undefined reference to
> >> `omap2_prm_set_mod_reg_bits'
> >> > arch/arm/mach-omap2/prcm.c:108: undefined reference to
> >> `omap2_prm_read_mod_reg'
> >> > arch/arm/mach-omap2/built-in.o: In function
> >> `omap_prcm_get_reset_sources':
> >> > arch/arm/mach-omap2/prcm.c:53: undefined reference to
> >> `omap2_prm_read_mod_reg'
> >> > arch/arm/mach-omap2/built-in.o: In function
> >> `clkdm_clear_all_wkdeps':
> >> > arch/arm/mach-omap2/clockdomain.c:545: undefined reference to
> >> `omap2_prm_clear_mod_reg_bits'
> >> > arch/arm/mach-omap2/built-in.o: In function `clkdm_del_wkdep':
> >> > arch/arm/mach-omap2/clockdomain.c:475: undefined reference to
> >> `omap2_prm_clear_mod_reg_bits'
> >> > arch/arm/mach-omap2/built-in.o: In function `clkdm_read_wkdep':
> >> > arch/arm/mach-omap2/clockdomain.c:511: undefined reference to
> >> `omap2_prm_read_mod_bits_shift'
> >> > arch/arm/mach-omap2/built-in.o: In function `clkdm_add_wkdep':
> >> > arch/arm/mach-omap2/clockdomain.c:440: undefined reference to
> >> `omap2_prm_set_mod_reg_bits'
> >> > make: *** [.tmp_vmlinux1] Error 1
> >> >
> >> > This patch adds stubs for these functions so that build
> continues
> >> to work.
> >> >
> >> > Probably alternately the build can be fixed as below but that
> not
> >> seems to
> >> > be the right way.
> >>
> >> Since these functions now return 0, maybe it would be better to
> call
> >> WARN() or BUG() in these functions for OMAP4. Otherwise, they
> are
> >> going
> >> to silently do the wrong thing, and someone needs to fix any
> usage
> >> of
> >> these functions where they shouldn't be used. e.g., in mach-
> >> omap2/prcm.c
> >> or mach-omap2/pm-debug.c ...
> >>
> > Good point. Will update the patch accordingly and repost.
>
> Please use WARN() instead of BUG() as this is not worthy of causing
> a
> panic() for the whole kernel.
>
Yes. I plan to use WARN_ONCE()
Regards,
Santosh
^ permalink raw reply
* [PATCH] leds/h1940: Use gpiolib for latch access / fix build failure
From: Vasily Khoruzhick @ 2011-01-05 7:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110104153725.2f3fede2.akpm@linux-foundation.org>
On Wednesday 05 January 2011 01:37:25 Andrew Morton wrote:
> On Fri, 10 Dec 2010 00:16:57 +0200
>
> Vasily Khoruzhick <anarsoul@gmail.com> wrote:
> > On Friday 10 December 2010 00:04:52 Peter Huewe wrote:
> > > This patch fixes a build failure by converting leds-h1940.c to use
> > > gpiolib for latch access introduced by 14477095abc6
> > > (ARM: h1940: Use gpiolib for latch access)
> > >
> > > Unfortunately this driver was not converted back then.
> >
> > I sent similar patch (however, my patch does gpio_request/gpio_free)
> > ~month ago.
> >
> > Here's link:
> > http://www.spinics.net/lists/arm-kernel/msg103429.html
>
> So which patch to use?
>
> I queued Peter's patch because it's simpler. I queued it for
> 2.6.38-rc1, taged for backporting into 2.6.37.x, so we have a bit of
> time to think about it.
It's simplier, but it does not request gpio before use. It will work, but will
print nasty warning.
Regards,
Vasily
^ permalink raw reply
* [PATCH 2/4] arm: Kconfig: remove duplicated GENERIC_HARDIRQS entry
From: Felipe Balbi @ 2011-01-05 6:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110104205445.GF25121@pengutronix.de>
Hi,
On Tue, Jan 04, 2011 at 09:54:45PM +0100, Uwe Kleine-K?nig wrote:
> > If you look at kernel/irq/Kconfig (as I did with the original patch)
> > you'd notice kernel/irq/Kconfig defines both of these symbols being
> > removed when HAVE_GENERIC_HARDIRQS is enabled.
> >
> > If you read the discussion in the previous version of this patch set,
> > you'd notice that the removal of this was specifically requested.
> >
> > It's very tiresome to have to re-explain these things. Please take
> > some more time to research the points you bring up, rather than
> I don't agree here 100%. IMHO the commit log was not good enough for
> the change introduced by the patch (and Felipe's reply suggests that he
> agrees). I could still research it, but:
>
> - it was not obvious for me there was a previous version (no "v2" or
> similar in the patch subject);
> - for me it would take say 5 minutes to check, the author knows
> the answer to my question immediately (at least he should);
> - after a research I could suggest a better wording, but I don't care
> much if it's me or Felipe who comes up with a better text.
>
> So all in all I'm still confident that my mail was OK.
No need to fight over a simple change, here it is updated.
--
balbi
^ permalink raw reply
* [PATCH 1/4] arm: omap: gpio: don't access irq_desc array directly
From: Felipe Balbi @ 2011-01-05 6:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87r5cs42p1.fsf@ti.com>
On Tue, Jan 04, 2011 at 04:24:58PM -0800, Kevin Hilman wrote:
> Felipe Balbi <balbi@ti.com> writes:
>
> > Instead of accessing the irq_desc array directly
> > we can use irq_to_desc(irq). That will allow us to,
> > if wanted, select SPARSE_IRQ and irq_descs will be
> > added to a radix tree, instead of a array.
> >
> > Signed-off-by: Felipe Balbi <balbi@ti.com>
>
> Can you refresh this one against Tony's omap-for-linus branch. The GPIO
> omap_device/hwmod conversion changed things around a bit and this patch
> doesn't apply.
>
> After that, you can send separately, and I'll queue this one along with
> some other GPIO core fixes for the 2.6.38-rc series after -rc1 comes
> out.
Sure, it's attached to this mail.
--
balbi
^ permalink raw reply
* [PATCH] arm: omap: gpio: don't access irq_desc array directly
From: Felipe Balbi @ 2011-01-05 6:46 UTC (permalink / raw)
To: linux-arm-kernel
Instead of accessing the irq_desc array directly
we can use irq_to_desc(irq). That will allow us to,
if wanted, select SPARSE_IRQ and irq_descs will be
added to a radix tree, instead of a array.
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
arch/arm/plat-omap/gpio.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 1f98e0b..197a6c0 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -756,8 +756,10 @@ static int gpio_irq_type(unsigned irq, unsigned type)
spin_lock_irqsave(&bank->lock, flags);
retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
if (retval == 0) {
- irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
- irq_desc[irq].status |= type;
+ struct irq_desc *d = irq_to_desc(irq);
+
+ d->status &= ~IRQ_TYPE_SENSE_MASK;
+ d->status |= type;
}
spin_unlock_irqrestore(&bank->lock, flags);
@@ -1671,7 +1673,9 @@ static void __init omap_gpio_chip_init(struct gpio_bank *bank)
for (j = bank->virtual_irq_start;
j < bank->virtual_irq_start + bank_width; j++) {
- lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class);
+ struct irq_desc *d = irq_to_desc(j);
+
+ lockdep_set_class(&d->lock, &gpio_lock_class);
set_irq_chip_data(j, bank);
if (bank_is_mpuio(bank))
set_irq_chip(j, &mpuio_irq_chip);
--
1.7.3.4.598.g85356
--b5gNqxB1S1yM7hjW--
^ permalink raw reply related
* Kernel 2.6.35.7 Oops caused by might_sleep() on ARMv7
From: TAO HU @ 2011-01-05 6:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTi=mrwX0UPH5H+XWYQ=D6D2jXhkEoqdrNgodsCmt@mail.gmail.com>
Hi, All
I'm getting kernel run on OMAP4430 chip (ARMv7, dual core), and got an
unexpected Oops caused by might_sleep() function. While that happened,
I was performing system test which almost consumed all system memory.
Based on Oops log below, might_sleep() threw out an unexpected warning
in page fault exception triggered by short of memory while calling
system call (by SWI exception). This should be a normal scenario, but,
kernel doesn't seem to handle it fine. ?Any thoughts ?
Oops log:
<6>[35377.073242] request_suspend_state: wakeup (0->0) at
32812699437166 (2010-12-29 19:08:41.273678467 UTC)
<6>[35379.468200] input: sensors as /devices/virtual/input/input9
<6>[35380.344421] usb_ether_get_stats
<6>[35380.362335] usb_ether_get_stats
<6>[35380.399444] usb_ether_get_stats
<6>[35380.417022] usb_ether_get_stats
<6>[35380.618469] usb_ether_get_stats
<3>[35391.279327] init: untracked pid 25171 exited
<4>[35393.306610] events/0: page allocation failure. order:1, mode:0x20
<4>[35393.313140] [<c004b7a0>] (unwind_backtrace+0x0/0xf0) from
[<c00f2df8>] (__alloc_pages_nodemask+0x568/0x6e8)
<4>[35393.323455] [<c00f2df8>] (__alloc_pages_nodemask+0x568/0x6e8)
from [<c0117a64>] (cache_grow.clone.0+0xac/0x3e8)
<4>[35393.334167] [<c0117a64>] (cache_grow.clone.0+0xac/0x3e8) from
[<c011a0a0>] (__kmalloc_track_caller+0x3f4/0x6cc)
<4>[35393.344848] [<c011a0a0>] (__kmalloc_track_caller+0x3f4/0x6cc)
from [<c0373264>] (__alloc_skb+0x50/0xe0)
<4>[35393.354827] [<c0373264>] (__alloc_skb+0x50/0xe0) from
[<bf030020>] (st_int_recv+0x370/0x48c [st_drv])
<4>[35393.364593] [<bf030020>] (st_int_recv+0x370/0x48c [st_drv]) from
[<bf02f018>] (st_tty_receive+0x18/0x20 [st_drv])
<4>[35393.375488] [<bf02f018>] (st_tty_receive+0x18/0x20 [st_drv])
from [<c0240ae0>] (flush_to_ldisc+0xe0/0x180)
<4>[35393.385711] [<c0240ae0>] (flush_to_ldisc+0xe0/0x180) from
[<c00a4cac>] (worker_thread+0x1e4/0x278)
<4>[35393.395202] [<c00a4cac>] (worker_thread+0x1e4/0x278) from
[<c00a8ab0>] (kthread+0x78/0x80)
<4>[35393.403961] [<c00a8ab0>] (kthread+0x78/0x80) from [<c00462cc>]
(kernel_thread_exit+0x0/0x8)
<4>[35393.412811] Mem-info:
<4>[35393.415222] Normal per-cpu:
<4>[35393.418182] CPU??? 0: hi:? 186, btch:? 31 usd:?? 5
<4>[35393.423248] CPU??? 1: hi:? 186, btch:? 31 usd:? 91
<4>[35393.428314] active_anon:15917 inactive_anon:15771 isolated_anon:1
<4>[35393.428314]? active_file:5235 inactive_file:7587 isolated_file:0
<4>[35393.428344]? unevictable:50762 dirty:56 writeback:0 unstable:0
<4>[35393.428344]? free:1037 slab_reclaimable:1224 slab_unreclaimable:3021
<4>[35393.428344]? mapped:12461 shmem:93 pagetables:3545 bounce:0
<4>[35393.459930] Normal free:4148kB min:2848kB low:3560kB high:4272kB
active_anon:63668kB inactive_anon:63084kB active_file:20940kB
inactive_file:30348kB unevictable:203048kB isolated(anon):4kB
isolated(file):0kB present:508000kB mlocked:0kB dirty:224kB
writeback:0kB mapped:49844kB shmem:372kB slab_reclaimable:4896kB
slab_unreclaimable:12084kB kernel_stack:3664kB pagetables:14180kB
unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:32
all_unreclaimable? no
<4>[35393.502685] lowmem_reserve[]: 0 0 0
<4>[35393.506378] Normal: 1037*4kB 0*8kB 0*16kB 0*32kB 0*64kB 0*128kB
0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 4148kB
<4>[35393.517517] 63672 total pagecache pages
<4>[35393.521545] 0 pages in swap cache
<4>[35393.525054] Swap cache stats: add 0, delete 0, find 0/0
<4>[35393.530578] Free swap? = 0kB
<4>[35393.533630] Total swap = 0kB
<4>[35393.555419] 128000 pages of RAM
<4>[35393.558746] 1790 free pages
<4>[35393.561676] 17305 reserved pages
<4>[35393.565093] 4254 slab pages
<4>[35393.568054] 127057 pages shared
<4>[35393.571350] 0 pages swap cached
<3>[35393.596527] (stc): Can't allocate mem for new packet
<3>[35398.317199] hci_cmd_task: hci0 command tx timeout
<3>[35403.916595] BUG: sleeping function called from invalid context
at /Volumes/data/hudson/workspace/integrated_device-cdma-solana-eng_main-dev_linux_continuous/platform/kernel/omap4/arch/arm/mm/fault.c:295
<3>[35403.935455] in_atomic(): 0, irqs_disabled(): 128, pid: 25390,
name: Thread-9
<4>[35403.942901] [<c004b7a0>] (unwind_backtrace+0x0/0xf0) from
[<c007eb24>] (__might_sleep+0x11c/0x148)
<4>[35403.952301] [<c007eb24>] (__might_sleep+0x11c/0x148) from
[<c004eccc>] (do_page_fault+0xa8/0x2e8)
<4>[35403.961608] [<c004eccc>] (do_page_fault+0xa8/0x2e8) from
[<c0044488>] (do_DataAbort+0x34/0xa8)
<4>[35403.970642] [<c0044488>] (do_DataAbort+0x34/0xa8) from
[<c0044bec>] (__dabt_svc+0x4c/0x60)
<4>[35403.979309] Exception stack(0xd1b79f68 to 0xd1b79fb0)
<4>[35403.984588] 9f60:?????????????????? 4624d868 00020241 00000180
4847ba4c 00000241 00228e58
<4>[35403.993164] 9f80: 00000180 00000005 20000010 43c66d8c 43c66d74
46251a60 ad12e228 d1b79fb0
<4>[35404.001739] 9fa0: afd0da0c c0045228 60000093 ffffffff
<4>[35404.007019] [<c0044bec>] (__dabt_svc+0x4c/0x60) from
[<c0045228>] (vector_swi+0x28/0x88)
^ permalink raw reply
* [RFC 1/5] ARM: P2V: separate PHYS_OFFSET from platform definitions
From: Uwe Kleine-König @ 2011-01-05 6:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110105000444.GA1085@n2100.arm.linux.org.uk>
Hello Russell,
On Wed, Jan 05, 2011 at 12:04:44AM +0000, Russell King - ARM Linux wrote:
> On Tue, Jan 04, 2011 at 10:23:59PM +0100, Uwe Kleine-K?nig wrote:
> > Hello Russell,
> >
> > On Tue, Jan 04, 2011 at 08:22:17PM +0000, Russell King - ARM Linux wrote:
> > > This uncouple PHYS_OFFSET from the platform definitions, thereby
> > > facilitating run-time computation of the physical memory offset.
> > >
> > > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> > > ---
> > > arch/arm/include/asm/memory.h | 2 ++
> > > arch/arm/kernel/tcm.c | 2 +-
> > > arch/arm/mach-aaec2000/include/mach/memory.h | 2 +-
> > > arch/arm/mach-at91/include/mach/memory.h | 2 +-
> > > arch/arm/mach-bcmring/include/mach/hardware.h | 2 +-
> > > arch/arm/mach-bcmring/include/mach/memory.h | 2 +-
> > > arch/arm/mach-clps711x/include/mach/memory.h | 2 +-
> > > arch/arm/mach-cns3xxx/include/mach/memory.h | 2 +-
> > > arch/arm/mach-davinci/include/mach/memory.h | 4 ++--
> > > arch/arm/mach-dove/include/mach/memory.h | 2 +-
> > > arch/arm/mach-ebsa110/include/mach/memory.h | 2 +-
> > > arch/arm/mach-ep93xx/include/mach/memory.h | 10 +++++-----
> > > arch/arm/mach-footbridge/include/mach/memory.h | 2 +-
> > > arch/arm/mach-h720x/include/mach/memory.h | 2 +-
> > > arch/arm/mach-integrator/include/mach/memory.h | 2 +-
> > > arch/arm/mach-iop13xx/include/mach/memory.h | 2 +-
> > > arch/arm/mach-iop32x/include/mach/memory.h | 2 +-
> > > arch/arm/mach-iop33x/include/mach/memory.h | 2 +-
> > > arch/arm/mach-ixp2000/include/mach/memory.h | 2 +-
> > > arch/arm/mach-ixp23xx/include/mach/memory.h | 2 +-
> > > arch/arm/mach-ixp4xx/include/mach/memory.h | 2 +-
> > > arch/arm/mach-kirkwood/include/mach/memory.h | 2 +-
> > > arch/arm/mach-ks8695/include/mach/memory.h | 2 +-
> > > arch/arm/mach-lh7a40x/include/mach/memory.h | 2 +-
> > > arch/arm/mach-loki/include/mach/memory.h | 2 +-
> > > arch/arm/mach-lpc32xx/include/mach/memory.h | 2 +-
> > > arch/arm/mach-mmp/include/mach/memory.h | 2 +-
> > > arch/arm/mach-msm/board-msm7x30.c | 2 +-
> > > arch/arm/mach-msm/include/mach/memory.h | 10 +++++-----
> > > arch/arm/mach-mv78xx0/include/mach/memory.h | 2 +-
> > > arch/arm/mach-mx3/mach-kzm_arm11_01.c | 2 +-
> > > arch/arm/mach-netx/include/mach/memory.h | 2 +-
> > > arch/arm/mach-nomadik/include/mach/memory.h | 2 +-
> > > arch/arm/mach-ns9xxx/include/mach/memory.h | 2 +-
> > > arch/arm/mach-nuc93x/include/mach/memory.h | 2 +-
> > > arch/arm/mach-orion5x/include/mach/memory.h | 2 +-
> > > arch/arm/mach-pnx4008/include/mach/memory.h | 2 +-
> > > arch/arm/mach-pxa/include/mach/memory.h | 2 +-
> > > arch/arm/mach-realview/include/mach/memory.h | 4 ++--
> > > arch/arm/mach-rpc/include/mach/memory.h | 2 +-
> > > arch/arm/mach-s3c2400/include/mach/memory.h | 2 +-
> > > arch/arm/mach-s3c2410/include/mach/memory.h | 2 +-
> > > arch/arm/mach-s3c24a0/include/mach/memory.h | 2 +-
> > > arch/arm/mach-s3c64xx/include/mach/memory.h | 2 +-
> > > arch/arm/mach-s5p6442/include/mach/memory.h | 2 +-
> > > arch/arm/mach-s5p64x0/include/mach/memory.h | 2 +-
> > > arch/arm/mach-s5pc100/include/mach/memory.h | 2 +-
> > > arch/arm/mach-s5pv210/include/mach/memory.h | 2 +-
> > > arch/arm/mach-s5pv310/include/mach/memory.h | 2 +-
> > > arch/arm/mach-sa1100/include/mach/memory.h | 2 +-
> > > arch/arm/mach-shark/include/mach/memory.h | 2 +-
> > > arch/arm/mach-shmobile/include/mach/memory.h | 2 +-
> > > arch/arm/mach-tegra/include/mach/memory.h | 2 +-
> > > arch/arm/mach-u300/include/mach/memory.h | 6 +++---
> > > arch/arm/mach-u300/u300.c | 2 +-
> > > arch/arm/mach-ux500/include/mach/memory.h | 2 +-
> > > arch/arm/mach-versatile/include/mach/memory.h | 2 +-
> > > arch/arm/mach-vexpress/include/mach/memory.h | 2 +-
> > > arch/arm/mach-w90x900/include/mach/memory.h | 2 +-
> > > arch/arm/plat-omap/include/plat/memory.h | 4 ++--
> > > arch/arm/plat-spear/include/plat/memory.h | 2 +-
> > > arch/arm/plat-stmp3xxx/include/mach/memory.h | 2 +-
> > > arch/arm/plat-tcc/include/mach/memory.h | 2 +-
> > > 63 files changed, 77 insertions(+), 75 deletions(-)
> > You didn't touch arch/arm/plat-mxc/include/mach/memory.h which defines
> > PHYS_OFFSET, too. I assume you just missed these?
>
> Grr.
>
> That's because it didn't match the '#define *PHYS_OFFSET' regexp I used
> to find all the definitions. This is exactly why being different from
> everyone else is a bad idea - you get missed.
I'm sure now you already noticed for yourself you missed
arch/arm/mach-gemini/include/mach/memory.h, too.
(The command I used to find this is
git grep -E '#[[:blank:]]*define[[:blank:]]+PHYS_OFFSET' arch/arm | grep -v '#define *PHYS_OFFSET'
in case someone used tabs after the define; doesn't seem to be the case
though.)
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [Oops] Kernel 2.6.35.7 Oops caused by might_sleep() on ARMv7
From: ShiYong LI @ 2011-01-05 5:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTikbEEUUoZ-+f7EGLrOQ+2n0+EaZXNSEH39bNFiY@mail.gmail.com>
Hi,
I'm getting kernel run on OMAP4430 chip (ARMv7, dual core), and got an
unexpected Oops caused by might_sleep() function. While that happened,
I was performing system test which almost consumed all system memory.
Based on Oops log below, might_sleep() threw out an unexpected warning
in page fault exception triggered by short of memory while calling
system call (by SWI exception). This should be a normal scenario, but,
kernel doesn't seem to handle it fine. ?Any thoughts ?
Oops log:
<6>[35377.073242] request_suspend_state: wakeup (0->0) at
32812699437166 (2010-12-29 19:08:41.273678467 UTC)
<6>[35379.468200] input: sensors as /devices/virtual/input/input9
<6>[35380.344421] usb_ether_get_stats
<6>[35380.362335] usb_ether_get_stats
<6>[35380.399444] usb_ether_get_stats
<6>[35380.417022] usb_ether_get_stats
<6>[35380.618469] usb_ether_get_stats
<3>[35391.279327] init: untracked pid 25171 exited
<4>[35393.306610] events/0: page allocation failure. order:1, mode:0x20
<4>[35393.313140] [<c004b7a0>] (unwind_backtrace+0x0/0xf0) from
[<c00f2df8>] (__alloc_pages_nodemask+0x568/0x6e8)
<4>[35393.323455] [<c00f2df8>] (__alloc_pages_nodemask+0x568/0x6e8)
from [<c0117a64>] (cache_grow.clone.0+0xac/0x3e8)
<4>[35393.334167] [<c0117a64>] (cache_grow.clone.0+0xac/0x3e8) from
[<c011a0a0>] (__kmalloc_track_caller+0x3f4/0x6cc)
<4>[35393.344848] [<c011a0a0>] (__kmalloc_track_caller+0x3f4/0x6cc)
from [<c0373264>] (__alloc_skb+0x50/0xe0)
<4>[35393.354827] [<c0373264>] (__alloc_skb+0x50/0xe0) from
[<bf030020>] (st_int_recv+0x370/0x48c [st_drv])
<4>[35393.364593] [<bf030020>] (st_int_recv+0x370/0x48c [st_drv]) from
[<bf02f018>] (st_tty_receive+0x18/0x20 [st_drv])
<4>[35393.375488] [<bf02f018>] (st_tty_receive+0x18/0x20 [st_drv])
from [<c0240ae0>] (flush_to_ldisc+0xe0/0x180)
<4>[35393.385711] [<c0240ae0>] (flush_to_ldisc+0xe0/0x180) from
[<c00a4cac>] (worker_thread+0x1e4/0x278)
<4>[35393.395202] [<c00a4cac>] (worker_thread+0x1e4/0x278) from
[<c00a8ab0>] (kthread+0x78/0x80)
<4>[35393.403961] [<c00a8ab0>] (kthread+0x78/0x80) from [<c00462cc>]
(kernel_thread_exit+0x0/0x8)
<4>[35393.412811] Mem-info:
<4>[35393.415222] Normal per-cpu:
<4>[35393.418182] CPU??? 0: hi:? 186, btch:? 31 usd:?? 5
<4>[35393.423248] CPU??? 1: hi:? 186, btch:? 31 usd:? 91
<4>[35393.428314] active_anon:15917 inactive_anon:15771 isolated_anon:1
<4>[35393.428314]? active_file:5235 inactive_file:7587 isolated_file:0
<4>[35393.428344]? unevictable:50762 dirty:56 writeback:0 unstable:0
<4>[35393.428344]? free:1037 slab_reclaimable:1224 slab_unreclaimable:3021
<4>[35393.428344]? mapped:12461 shmem:93 pagetables:3545 bounce:0
<4>[35393.459930] Normal free:4148kB min:2848kB low:3560kB high:4272kB
active_anon:63668kB inactive_anon:63084kB active_file:20940kB
inactive_file:30348kB unevictable:203048kB isolated(anon):4kB
isolated(file):0kB present:508000kB mlocked:0kB dirty:224kB
writeback:0kB mapped:49844kB shmem:372kB slab_reclaimable:4896kB
slab_unreclaimable:12084kB kernel_stack:3664kB pagetables:14180kB
unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:32
all_unreclaimable? no
<4>[35393.502685] lowmem_reserve[]: 0 0 0
<4>[35393.506378] Normal: 1037*4kB 0*8kB 0*16kB 0*32kB 0*64kB 0*128kB
0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 4148kB
<4>[35393.517517] 63672 total pagecache pages
<4>[35393.521545] 0 pages in swap cache
<4>[35393.525054] Swap cache stats: add 0, delete 0, find 0/0
<4>[35393.530578] Free swap? = 0kB
<4>[35393.533630] Total swap = 0kB
<4>[35393.555419] 128000 pages of RAM
<4>[35393.558746] 1790 free pages
<4>[35393.561676] 17305 reserved pages
<4>[35393.565093] 4254 slab pages
<4>[35393.568054] 127057 pages shared
<4>[35393.571350] 0 pages swap cached
<3>[35393.596527] (stc): Can't allocate mem for new packet
<3>[35398.317199] hci_cmd_task: hci0 command tx timeout
<3>[35403.916595] BUG: sleeping function called from invalid context
at /Volumes/data/hudson/workspace/integrated_device-cdma-solana-eng_main-dev_linux_continuous/platform/kernel/omap4/arch/arm/mm/fault.c:295
<3>[35403.935455] in_atomic(): 0, irqs_disabled(): 128, pid: 25390,
name: Thread-9
<4>[35403.942901] [<c004b7a0>] (unwind_backtrace+0x0/0xf0) from
[<c007eb24>] (__might_sleep+0x11c/0x148)
<4>[35403.952301] [<c007eb24>] (__might_sleep+0x11c/0x148) from
[<c004eccc>] (do_page_fault+0xa8/0x2e8)
<4>[35403.961608] [<c004eccc>] (do_page_fault+0xa8/0x2e8) from
[<c0044488>] (do_DataAbort+0x34/0xa8)
<4>[35403.970642] [<c0044488>] (do_DataAbort+0x34/0xa8) from
[<c0044bec>] (__dabt_svc+0x4c/0x60)
<4>[35403.979309] Exception stack(0xd1b79f68 to 0xd1b79fb0)
<4>[35403.984588] 9f60:?????????????????? 4624d868 00020241 00000180
4847ba4c 00000241 00228e58
<4>[35403.993164] 9f80: 00000180 00000005 20000010 43c66d8c 43c66d74
46251a60 ad12e228 d1b79fb0
<4>[35404.001739] 9fa0: afd0da0c c0045228 60000093 ffffffff
<4>[35404.007019] [<c0044bec>] (__dabt_svc+0x4c/0x60) from
[<c0045228>] (vector_swi+0x28/0x88)
--
Thanks & Best Regards
Shiyong
^ permalink raw reply
* [PATCH v2 3/3] ahci_platform: add support for CNS3xxx SoC devices
From: mkl0301 at gmail.com @ 2011-01-05 5:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294206187-11487-1-git-send-email-mkl0301@gmail.com>
From: Mac Lin <mkl0301@gmail.com>
CNS3xxx override the softreset function of ahci_platform ahci_softreset by
cns3xxx_ahci_softreset, which would retry ahci_do_softreset again with pmp=0 if
pmp=15 failed, for the controller has problem receiving D2H Reg FIS of the
different PMP setting of the previous sent H2D Reg FIS.
Following describe the isssue with original ahci_platform driver on
linux-2.6.37-rc3, arm/cns3xxx.
If CONFIG_SATA_PMP is enabled, while not using multiplier and connect the disks
directly to the board, the disk cannot be found due to software reset always
failed.
ahci ahci.0: forcing PORTS_IMPL to 0x3
ahci ahci.0: AHCI 0001.0100 32 slots 2 ports 3 Gbps 0x3 impl platform mode
ahci ahci.0: flags: ncq sntf pm led clo only pmp pio slum part ccc
scsi0 : ahci_platform
scsi1 : ahci_platform
ata1: SATA max UDMA/133 irq_stat 0x00400040, connection status changed irq 65
ata2: SATA max UDMA/133 mmio [mem 0x83000000-0x83ffffff] port 0x180 irq 65
ata2: SATA link down (SStatus 0 SControl 300)
ata1: link is slow to respond, please be patient (ready=0)
ata1: softreset failed (device not ready)
ata1: link is slow to respond, please be patient (ready=0)
ata1: softreset failed (device not ready)
ata1: link is slow to respond, please be patient (ready=0)
ata1: softreset failed (device not ready)
ata1: limiting SATA link speed to 1.5 Gbps
ata1: SATA link down (SStatus 1 SControl 310)
While using multiplier with CONFIG_SATA_PMP enabled, or using disks directly
without CONFIG_SATA_PMP have no issue. It seems the device is sending D2H Reg
FIS, but controller is not reflecting it on any known means.
Signed-off-by: Mac Lin <mkl0301@gmail.com>
---
arch/arm/mach-cns3xxx/devices.c | 2 +-
drivers/ata/Kconfig | 11 +++++++
drivers/ata/Makefile | 1 +
drivers/ata/ahci_cns3xxx.c | 62 +++++++++++++++++++++++++++++++++++++++
drivers/ata/ahci_pltfm.c | 3 ++
drivers/ata/ahci_pltfm.h | 2 +
6 files changed, 80 insertions(+), 1 deletions(-)
create mode 100644 drivers/ata/ahci_cns3xxx.c
diff --git a/arch/arm/mach-cns3xxx/devices.c b/arch/arm/mach-cns3xxx/devices.c
index 50b4d31..b496f02 100644
--- a/arch/arm/mach-cns3xxx/devices.c
+++ b/arch/arm/mach-cns3xxx/devices.c
@@ -40,7 +40,7 @@ static struct resource cns3xxx_ahci_resource[] = {
static u64 cns3xxx_ahci_dmamask = DMA_BIT_MASK(32);
static struct platform_device cns3xxx_ahci_pdev = {
- .name = "ahci",
+ .name = "ahci-cns3xxx",
.id = 0,
.resource = cns3xxx_ahci_resource,
.num_resources = ARRAY_SIZE(cns3xxx_ahci_resource),
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 36e2319..5d8b1a3 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -75,6 +75,17 @@ config SATA_AHCI_PLATFORM
If unsure, say N.
+config SATA_AHCI_CNS3XXX
+ bool "AHCI Support on the Cavium Networks CNS3xxx SOC"
+ depends on ARCH_CNS3XXX
+ depends on SATA_AHCI_PLATFORM
+ help
+ This option enables AHCI platform driver to support CNS3xxx
+ System-on-Chip devices. This is only needed when using CNS3xxx AHCI
+ controller.
+
+ If unsure, say N.
+
config SATA_FSL
tristate "Freescale 3.0Gbps SATA support"
depends on FSL_SOC
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 5b62be8..a0745e5 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -100,6 +100,7 @@ obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o
ahci_platform-y := ahci_pltfm.o
+ahci_platform-$(CONFIG_SATA_AHCI_CNS3XXX) += ahci_cns3xxx.o
libata-y := libata-core.o libata-scsi.o libata-eh.o libata-transport.o
libata-$(CONFIG_ATA_SFF) += libata-sff.o
diff --git a/drivers/ata/ahci_cns3xxx.c b/drivers/ata/ahci_cns3xxx.c
new file mode 100644
index 0000000..f7a238e
--- /dev/null
+++ b/drivers/ata/ahci_cns3xxx.c
@@ -0,0 +1,62 @@
+/*
+ * AHCI support for CNS3xxx SoC
+ *
+ * Copyright 2010 MontaVista Software, LLC.
+ * Copyright 2010 Cavium Networks
+ *
+ * Authors: Anton Vorontsov <avorontsov@mvista.com>
+ * Mac Lin <mkl0301@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/libata.h>
+#include <linux/ahci_platform.h>
+#include "ahci.h"
+
+static int cns3xxx_ahci_softreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline)
+{
+ int pmp = sata_srst_pmp(link);
+ int ret;
+ DPRINTK("ENTER\n");
+
+ ret = ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready);
+ if (pmp && ret)
+ return ahci_do_softreset(link, class, 0, deadline,
+ ahci_check_ready);
+ else
+ return ret;
+}
+
+static int cns3xxx_ahci_init(struct device *dev, void __iomem *addr)
+{
+ /*
+ * TODO: move cns3xxx_ahci_init to here after cns3xxx_pwr*() calls are
+ * thread-safe
+ */
+
+ return 0;
+}
+
+static struct ata_port_operations cns3xxx_ahci_ops = {
+ .inherits = &ahci_ops,
+ .softreset = cns3xxx_ahci_softreset,
+};
+
+static const struct ata_port_info cns3xxx_ata_port_info = {
+ .flags = AHCI_FLAG_COMMON,
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &cns3xxx_ahci_ops,
+};
+
+struct ahci_platform_data cns3xxx_ahci_platform_data = {
+ .init = cns3xxx_ahci_init,
+ .ata_port_info = &cns3xxx_ata_port_info,
+ .force_port_map = 0,
+ .mask_port_map = 0,
+};
+
diff --git a/drivers/ata/ahci_pltfm.c b/drivers/ata/ahci_pltfm.c
index 6579d55..03406f8 100644
--- a/drivers/ata/ahci_pltfm.c
+++ b/drivers/ata/ahci_pltfm.c
@@ -179,6 +179,9 @@ static int __devexit ahci_remove(struct platform_device *pdev)
static const struct platform_device_id ahci_pltfm_ids[] = {
{ "ahci", },
+#ifdef CONFIG_SATA_AHCI_CNS3XXX
+ { "ahci-cns3xxx", (kernel_ulong_t)&cns3xxx_ahci_platform_data},
+#endif
{ },
};
MODULE_DEVICE_TABLE(platform, ahci_pltfm_ids);
diff --git a/drivers/ata/ahci_pltfm.h b/drivers/ata/ahci_pltfm.h
index b66390c..e07bf70 100644
--- a/drivers/ata/ahci_pltfm.h
+++ b/drivers/ata/ahci_pltfm.h
@@ -13,5 +13,7 @@
#ifndef _DRIVERS_SATA_AHCI_PLTFM_H
#define _DRIVERS_SATA_AHCI_PLTFM_H
+extern struct ahci_platform_data cns3xxx_ahci_platform_data;
+
#endif /* _DRIVERS_SATA_AHCI_PLTFM_H */
--
1.7.3
^ permalink raw reply related
* [PATCH v2 2/3] ahci_pltfm: switch to module device table matching
From: mkl0301 at gmail.com @ 2011-01-05 5:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294206187-11487-1-git-send-email-mkl0301@gmail.com>
From: Mac Lin <mkl0301@gmail.com>
Switch the driver to use module device table matching mechanism to add SoC-specific parts to the generic driver.
Signed-off-by: Mac Lin <mkl0301@gmail.com>
---
drivers/ata/ahci_pltfm.c | 14 +++++++++++++-
drivers/ata/ahci_pltfm.h | 17 +++++++++++++++++
2 files changed, 30 insertions(+), 1 deletions(-)
create mode 100644 drivers/ata/ahci_pltfm.h
diff --git a/drivers/ata/ahci_pltfm.c b/drivers/ata/ahci_pltfm.c
index 6fef1fa..6579d55 100644
--- a/drivers/ata/ahci_pltfm.c
+++ b/drivers/ata/ahci_pltfm.c
@@ -19,9 +19,11 @@
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/platform_device.h>
+#include <linux/mod_devicetable.h>
#include <linux/libata.h>
#include <linux/ahci_platform.h>
#include "ahci.h"
+#include "ahci_pltfm.h"
static struct scsi_host_template ahci_platform_sht = {
AHCI_SHT("ahci_platform"),
@@ -29,6 +31,7 @@ static struct scsi_host_template ahci_platform_sht = {
static int __init ahci_probe(struct platform_device *pdev)
{
+ const struct platform_device_id *platid = platform_get_device_id(pdev);
struct device *dev = &pdev->dev;
struct ahci_platform_data *pdata = dev->platform_data;
struct ata_port_info pi = {
@@ -46,6 +49,9 @@ static int __init ahci_probe(struct platform_device *pdev)
int i;
int rc;
+ if (!pdata && platid && platid->driver_data)
+ pdata = (void *)platid->driver_data;
+
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(dev, "no mmio space\n");
@@ -171,12 +177,19 @@ static int __devexit ahci_remove(struct platform_device *pdev)
return 0;
}
+static const struct platform_device_id ahci_pltfm_ids[] = {
+ { "ahci", },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, ahci_pltfm_ids);
+
static struct platform_driver ahci_driver = {
.remove = __devexit_p(ahci_remove),
.driver = {
.name = "ahci",
.owner = THIS_MODULE,
},
+ .id_table = ahci_pltfm_ids,
};
static int __init ahci_init(void)
@@ -194,4 +207,3 @@ module_exit(ahci_exit);
MODULE_DESCRIPTION("AHCI SATA platform driver");
MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:ahci");
diff --git a/drivers/ata/ahci_pltfm.h b/drivers/ata/ahci_pltfm.h
new file mode 100644
index 0000000..b66390c
--- /dev/null
+++ b/drivers/ata/ahci_pltfm.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2010 MontaVista Software, LLC.
+ * Copyright 2010 Cavium Networks
+ *
+ * Authors: Anton Vorontsov <avorontsov@mvista.com>
+ * Mac Lin <mkl0301@gmail.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.
+ */
+
+#ifndef _DRIVERS_SATA_AHCI_PLTFM_H
+#define _DRIVERS_SATA_AHCI_PLTFM_H
+
+#endif /* _DRIVERS_SATA_AHCI_PLTFM_H */
+
--
1.7.3
^ permalink raw reply related
* [PATCH v2 1/3] ahci_platform: rename to ahci_pltfm, but keep the original module name
From: mkl0301 at gmail.com @ 2011-01-05 5:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294206187-11487-1-git-send-email-mkl0301@gmail.com>
From: Mac Lin <mkl0301@gmail.com>
Due to build system limitations, intermediate and final objects can't have the
same names. And as we're going to start building SoC-specific objects, rename
ahci_platform to ahci_pltfm to be linked with SoC-specific objects into
ahci_platform.
Signed-off-by: Mac Lin <mkl0301@gmail.com>
---
drivers/ata/Makefile | 4 +-
drivers/ata/ahci_platform.c | 197 -------------------------------------------
drivers/ata/ahci_pltfm.c | 197 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 200 insertions(+), 198 deletions(-)
delete mode 100644 drivers/ata/ahci_platform.c
create mode 100644 drivers/ata/ahci_pltfm.c
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 2b67c90..5b62be8 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -3,7 +3,6 @@ obj-$(CONFIG_ATA) += libata.o
# non-SFF interface
obj-$(CONFIG_SATA_AHCI) += ahci.o libahci.o
-obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o
obj-$(CONFIG_SATA_FSL) += sata_fsl.o
obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
@@ -99,6 +98,9 @@ obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
# Should be last libata driver
obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
+obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o
+ahci_platform-y := ahci_pltfm.o
+
libata-y := libata-core.o libata-scsi.o libata-eh.o libata-transport.o
libata-$(CONFIG_ATA_SFF) += libata-sff.o
libata-$(CONFIG_SATA_PMP) += libata-pmp.o
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
deleted file mode 100644
index 6fef1fa..0000000
--- a/drivers/ata/ahci_platform.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * AHCI SATA platform driver
- *
- * Copyright 2004-2005 Red Hat, Inc.
- * Jeff Garzik <jgarzik@pobox.com>
- * Copyright 2010 MontaVista Software, LLC.
- * Anton Vorontsov <avorontsov@ru.mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/gfp.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/libata.h>
-#include <linux/ahci_platform.h>
-#include "ahci.h"
-
-static struct scsi_host_template ahci_platform_sht = {
- AHCI_SHT("ahci_platform"),
-};
-
-static int __init ahci_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct ahci_platform_data *pdata = dev->platform_data;
- struct ata_port_info pi = {
- .flags = AHCI_FLAG_COMMON,
- .pio_mask = ATA_PIO4,
- .udma_mask = ATA_UDMA6,
- .port_ops = &ahci_ops,
- };
- const struct ata_port_info *ppi[] = { &pi, NULL };
- struct ahci_host_priv *hpriv;
- struct ata_host *host;
- struct resource *mem;
- int irq;
- int n_ports;
- int i;
- int rc;
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem) {
- dev_err(dev, "no mmio space\n");
- return -EINVAL;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq <= 0) {
- dev_err(dev, "no irq\n");
- return -EINVAL;
- }
-
- if (pdata && pdata->ata_port_info)
- pi = *pdata->ata_port_info;
-
- hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
- if (!hpriv) {
- dev_err(dev, "can't alloc ahci_host_priv\n");
- return -ENOMEM;
- }
-
- hpriv->flags |= (unsigned long)pi.private_data;
-
- hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
- if (!hpriv->mmio) {
- dev_err(dev, "can't map %pR\n", mem);
- return -ENOMEM;
- }
-
- /*
- * Some platforms might need to prepare for mmio region access,
- * which could be done in the following init call. So, the mmio
- * region shouldn't be accessed before init (if provided) has
- * returned successfully.
- */
- if (pdata && pdata->init) {
- rc = pdata->init(dev, hpriv->mmio);
- if (rc)
- return rc;
- }
-
- ahci_save_initial_config(dev, hpriv,
- pdata ? pdata->force_port_map : 0,
- pdata ? pdata->mask_port_map : 0);
-
- /* prepare host */
- if (hpriv->cap & HOST_CAP_NCQ)
- pi.flags |= ATA_FLAG_NCQ;
-
- if (hpriv->cap & HOST_CAP_PMP)
- pi.flags |= ATA_FLAG_PMP;
-
- ahci_set_em_messages(hpriv, &pi);
-
- /* CAP.NP sometimes indicate the index of the last enabled
- * port, at other times, that of the last possible port, so
- * determining the maximum port number requires looking at
- * both CAP.NP and port_map.
- */
- n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
-
- host = ata_host_alloc_pinfo(dev, ppi, n_ports);
- if (!host) {
- rc = -ENOMEM;
- goto err0;
- }
-
- host->private_data = hpriv;
-
- if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
- host->flags |= ATA_HOST_PARALLEL_SCAN;
- else
- printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n");
-
- if (pi.flags & ATA_FLAG_EM)
- ahci_reset_em(host);
-
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
- ata_port_desc(ap, "mmio %pR", mem);
- ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
-
- /* set enclosure management message type */
- if (ap->flags & ATA_FLAG_EM)
- ap->em_message_type = hpriv->em_msg_type;
-
- /* disabled/not-implemented port */
- if (!(hpriv->port_map & (1 << i)))
- ap->ops = &ata_dummy_port_ops;
- }
-
- rc = ahci_reset_controller(host);
- if (rc)
- goto err0;
-
- ahci_init_controller(host);
- ahci_print_info(host, "platform");
-
- rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
- &ahci_platform_sht);
- if (rc)
- goto err0;
-
- return 0;
-err0:
- if (pdata && pdata->exit)
- pdata->exit(dev);
- return rc;
-}
-
-static int __devexit ahci_remove(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct ahci_platform_data *pdata = dev->platform_data;
- struct ata_host *host = dev_get_drvdata(dev);
-
- ata_host_detach(host);
-
- if (pdata && pdata->exit)
- pdata->exit(dev);
-
- return 0;
-}
-
-static struct platform_driver ahci_driver = {
- .remove = __devexit_p(ahci_remove),
- .driver = {
- .name = "ahci",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init ahci_init(void)
-{
- return platform_driver_probe(&ahci_driver, ahci_probe);
-}
-module_init(ahci_init);
-
-static void __exit ahci_exit(void)
-{
- platform_driver_unregister(&ahci_driver);
-}
-module_exit(ahci_exit);
-
-MODULE_DESCRIPTION("AHCI SATA platform driver");
-MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:ahci");
diff --git a/drivers/ata/ahci_pltfm.c b/drivers/ata/ahci_pltfm.c
new file mode 100644
index 0000000..6fef1fa
--- /dev/null
+++ b/drivers/ata/ahci_pltfm.c
@@ -0,0 +1,197 @@
+/*
+ * AHCI SATA platform driver
+ *
+ * Copyright 2004-2005 Red Hat, Inc.
+ * Jeff Garzik <jgarzik@pobox.com>
+ * Copyright 2010 MontaVista Software, LLC.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/gfp.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/libata.h>
+#include <linux/ahci_platform.h>
+#include "ahci.h"
+
+static struct scsi_host_template ahci_platform_sht = {
+ AHCI_SHT("ahci_platform"),
+};
+
+static int __init ahci_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ahci_platform_data *pdata = dev->platform_data;
+ struct ata_port_info pi = {
+ .flags = AHCI_FLAG_COMMON,
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_ops,
+ };
+ const struct ata_port_info *ppi[] = { &pi, NULL };
+ struct ahci_host_priv *hpriv;
+ struct ata_host *host;
+ struct resource *mem;
+ int irq;
+ int n_ports;
+ int i;
+ int rc;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(dev, "no mmio space\n");
+ return -EINVAL;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq <= 0) {
+ dev_err(dev, "no irq\n");
+ return -EINVAL;
+ }
+
+ if (pdata && pdata->ata_port_info)
+ pi = *pdata->ata_port_info;
+
+ hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv) {
+ dev_err(dev, "can't alloc ahci_host_priv\n");
+ return -ENOMEM;
+ }
+
+ hpriv->flags |= (unsigned long)pi.private_data;
+
+ hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
+ if (!hpriv->mmio) {
+ dev_err(dev, "can't map %pR\n", mem);
+ return -ENOMEM;
+ }
+
+ /*
+ * Some platforms might need to prepare for mmio region access,
+ * which could be done in the following init call. So, the mmio
+ * region shouldn't be accessed before init (if provided) has
+ * returned successfully.
+ */
+ if (pdata && pdata->init) {
+ rc = pdata->init(dev, hpriv->mmio);
+ if (rc)
+ return rc;
+ }
+
+ ahci_save_initial_config(dev, hpriv,
+ pdata ? pdata->force_port_map : 0,
+ pdata ? pdata->mask_port_map : 0);
+
+ /* prepare host */
+ if (hpriv->cap & HOST_CAP_NCQ)
+ pi.flags |= ATA_FLAG_NCQ;
+
+ if (hpriv->cap & HOST_CAP_PMP)
+ pi.flags |= ATA_FLAG_PMP;
+
+ ahci_set_em_messages(hpriv, &pi);
+
+ /* CAP.NP sometimes indicate the index of the last enabled
+ * port, at other times, that of the last possible port, so
+ * determining the maximum port number requires looking at
+ * both CAP.NP and port_map.
+ */
+ n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
+
+ host = ata_host_alloc_pinfo(dev, ppi, n_ports);
+ if (!host) {
+ rc = -ENOMEM;
+ goto err0;
+ }
+
+ host->private_data = hpriv;
+
+ if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
+ host->flags |= ATA_HOST_PARALLEL_SCAN;
+ else
+ printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n");
+
+ if (pi.flags & ATA_FLAG_EM)
+ ahci_reset_em(host);
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ ata_port_desc(ap, "mmio %pR", mem);
+ ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
+
+ /* set enclosure management message type */
+ if (ap->flags & ATA_FLAG_EM)
+ ap->em_message_type = hpriv->em_msg_type;
+
+ /* disabled/not-implemented port */
+ if (!(hpriv->port_map & (1 << i)))
+ ap->ops = &ata_dummy_port_ops;
+ }
+
+ rc = ahci_reset_controller(host);
+ if (rc)
+ goto err0;
+
+ ahci_init_controller(host);
+ ahci_print_info(host, "platform");
+
+ rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
+ &ahci_platform_sht);
+ if (rc)
+ goto err0;
+
+ return 0;
+err0:
+ if (pdata && pdata->exit)
+ pdata->exit(dev);
+ return rc;
+}
+
+static int __devexit ahci_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct ahci_platform_data *pdata = dev->platform_data;
+ struct ata_host *host = dev_get_drvdata(dev);
+
+ ata_host_detach(host);
+
+ if (pdata && pdata->exit)
+ pdata->exit(dev);
+
+ return 0;
+}
+
+static struct platform_driver ahci_driver = {
+ .remove = __devexit_p(ahci_remove),
+ .driver = {
+ .name = "ahci",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ahci_init(void)
+{
+ return platform_driver_probe(&ahci_driver, ahci_probe);
+}
+module_init(ahci_init);
+
+static void __exit ahci_exit(void)
+{
+ platform_driver_unregister(&ahci_driver);
+}
+module_exit(ahci_exit);
+
+MODULE_DESCRIPTION("AHCI SATA platform driver");
+MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ahci");
--
1.7.3
^ permalink raw reply related
* [PATCH v2 0/3] add CNS3xxx AHCI support
From: mkl0301 at gmail.com @ 2011-01-05 5:43 UTC (permalink / raw)
To: linux-arm-kernel
From: Mac Lin <mkl0301@gmail.com>
v2:
- Switch ahci_platform to module device table matching to add SoC specific support
v1: http://www.spinics.net/lists/arm-kernel/msg106236.html
- Add CNS3xxx SoC specific AHCI support
This patchset is based on linux-2.6.37-rc2
Mac Lin (3):
ahci_platform: rename to ahci_pltfm, but keep the original module name
ahci_pltfm: switch to module device table matching
ahci_platform: add support for CNS3xxx SoC devices
arch/arm/mach-cns3xxx/devices.c | 2 +-
drivers/ata/Kconfig | 11 ++
drivers/ata/Makefile | 5 +-
drivers/ata/ahci_cns3xxx.c | 62 +++++++++++
drivers/ata/ahci_platform.c | 197 ------------------------------------
drivers/ata/ahci_pltfm.c | 212 +++++++++++++++++++++++++++++++++++++++
drivers/ata/ahci_pltfm.h | 19 ++++
7 files changed, 309 insertions(+), 199 deletions(-)
create mode 100644 drivers/ata/ahci_cns3xxx.c
delete mode 100644 drivers/ata/ahci_platform.c
create mode 100644 drivers/ata/ahci_pltfm.c
create mode 100644 drivers/ata/ahci_pltfm.h
^ permalink raw reply
* Bug in arch-mmp board selection
From: Haojian Zhuang @ 2011-01-05 5:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTi=SX-KmcmP-cNN-59D+rSABQmSHEPQaYF0WFbGg@mail.gmail.com>
On Wed, Jan 5, 2011 at 12:57 PM, Mark F. Brown <mark.brown314@gmail.com> wrote:
> Hi Eric,
>
> PXA168 and PXA910 are based on PJ1 which is an ARMv5 compatible architecture
> MMP2 is a based on PJ4 which configured as ARMv6 currently (there are
> ARMv7 versions as well)
>
> Currently all SoCs are selectable under the "PXA168/910/MMP2" menu
> option which allows you to then select PXA168, PXA910, and MMP2 boards
> for one image. If you build this configuration this error occurs:
>
> ?AS ? ? ?arch/arm/kernel/entry-armv.o
> arch/arm/kernel/entry-armv.S: Assembler messages:
> arch/arm/kernel/entry-armv.S:212: Error: selected processor does not
> support `clrex'
> arch/arm/kernel/entry-armv.S:244: Error: selected processor does not
> support `clrex'
> arch/arm/kernel/entry-armv.S:302: Error: selected processor does not
> support `clrex'
> arch/arm/kernel/entry-armv.S:338: Error: selected processor does not
> support `clrex'
> make[1]: *** [arch/arm/kernel/entry-armv.o] Error 1
> make: *** [arch/arm/kernel] Error 2
>
You must build PJ1 and PJ4 together. Actually, I plan to add
ARCH_MMP2. So we can avoid this issue.
> I am aware we can resolve this by adding KConfig rules to prevent this
> scenario, but it leads to a deeper question. Why does selecting the
> board in turn select the CPU type instead of the user enabling the CPU
> type and then providing a set of boards for selection?
>
> e.g.
> config MACH_ZYLONITE2
> ? ? ? ?bool "Marvell's PXA168 Zylonite2 Development Board"
> ? ? ? --> select CPU_PXA168
>
^ permalink raw reply
* Bug in arch-mmp board selection
From: Mark F. Brown @ 2011-01-05 4:57 UTC (permalink / raw)
To: linux-arm-kernel
Hi Eric,
PXA168 and PXA910 are based on PJ1 which is an ARMv5 compatible architecture
MMP2 is a based on PJ4 which configured as ARMv6 currently (there are
ARMv7 versions as well)
Currently all SoCs are selectable under the "PXA168/910/MMP2" menu
option which allows you to then select PXA168, PXA910, and MMP2 boards
for one image. If you build this configuration this error occurs:
AS arch/arm/kernel/entry-armv.o
arch/arm/kernel/entry-armv.S: Assembler messages:
arch/arm/kernel/entry-armv.S:212: Error: selected processor does not
support `clrex'
arch/arm/kernel/entry-armv.S:244: Error: selected processor does not
support `clrex'
arch/arm/kernel/entry-armv.S:302: Error: selected processor does not
support `clrex'
arch/arm/kernel/entry-armv.S:338: Error: selected processor does not
support `clrex'
make[1]: *** [arch/arm/kernel/entry-armv.o] Error 1
make: *** [arch/arm/kernel] Error 2
I am aware we can resolve this by adding KConfig rules to prevent this
scenario, but it leads to a deeper question. Why does selecting the
board in turn select the CPU type instead of the user enabling the CPU
type and then providing a set of boards for selection?
e.g.
config MACH_ZYLONITE2
bool "Marvell's PXA168 Zylonite2 Development Board"
--> select CPU_PXA168
^ permalink raw reply
* [PATCH 0/2] Common struct clk implementation, v10
From: Jeremy Kerr @ 2011-01-05 3:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294199462.347935.472473715866.0.gpush@pororo>
Sorry about the repost, folks - lkml bounced my badly-encoded headers.
Cheers,
Jeremy
^ permalink raw reply
* [PATCH 2/2] clk: Generic support for fixed-rate clocks
From: Jeremy Kerr @ 2011-01-05 3:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294199462.347935.472473715866.0.gpush@pororo>
Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.
Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
---
include/linux/clk.h | 16 ++++++++++++++++
kernel/clk.c | 14 ++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 95c49b1..6cef9fe 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -164,6 +164,22 @@ static inline void clk_common_init(struct clk *clk)
mutex_init(&clk->lock.mutex);
}
+/* Simple fixed-rate clock */
+struct clk_fixed {
+ struct clk clk;
+ unsigned long rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+ .clk = INIT_CLK(name.clk, clk_fixed_ops), \
+ .rate = (r) \
+}
+
+#define DEFINE_CLK_FIXED(name, r) \
+ struct clk_fixed name = INIT_CLK_FIXED(name, r)
+
#else /* !CONFIG_USE_COMMON_STRUCT_CLK */
/*
diff --git a/kernel/clk.c b/kernel/clk.c
index 8de8fe3..6c38cc0 100644
--- a/kernel/clk.c
+++ b/kernel/clk.c
@@ -100,3 +100,17 @@ struct clk *clk_get_parent(struct clk *clk)
return ERR_PTR(-ENOSYS);
}
EXPORT_SYMBOL_GPL(clk_get_parent);
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+ return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+ .get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);
^ permalink raw reply related
* [PATCH 1/2] Add a common struct clk
From: Jeremy Kerr @ 2011-01-05 3:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294199462.347935.472473715866.0.gpush@pororo>
We currently have ~21 definitions of struct clk in the ARM architecture,
each defined on a per-platform basis. This makes it difficult to define
platform- (or architecture-) independent clock sources without making
assumptions about struct clk, and impossible to compile two
platforms with different struct clks into a single image.
This change is an effort to unify struct clk where possible, by defining
a common struct clk, containing a set of clock operations. Different
clock implementations can set their own operations, and have a standard
interface for generic code. The callback interface is exposed to the
kernel proper, while the clock implementations only need to be seen by
the platform internals.
This allows us to share clock code among platforms, and makes it
possible to dynamically create clock devices in platform-independent
code.
Platforms can enable the generic struct clock through
CONFIG_USE_COMMON_STRUCT_CLK. In this case, the clock infrastructure
consists of a common struct clk:
struct clk {
const struct clk_ops *ops;
unsigned int enable_count;
int flags;
union {
struct mutex mutex;
spinlock_t spinlock;
} lock;
};
And a set of clock operations (defined per type of clock):
struct clk_ops {
int (*enable)(struct clk *);
void (*disable)(struct clk *);
unsigned long (*get_rate)(struct clk *);
[...]
};
To define a hardware-specific clock, machine code can "subclass" the
struct clock into a new struct (adding any device-specific data), and
provide a set of operations:
struct clk_foo {
struct clk clk;
void __iomem *some_register;
};
struct clk_ops clk_foo_ops = {
.get_rate = clk_foo_get_rate,
};
The common clock definitions are based on a development patch from Ben
Herrenschmidt <benh@kernel.crashing.org>.
Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
Acked-by: Paulius Zaleckas <paulius.zaleckas@gmail.com>
---
arch/Kconfig | 3
include/linux/clk.h | 164 +++++++++++++++++++++++++++++++++++++++++---
kernel/Makefile | 1
kernel/clk.c | 102 +++++++++++++++++++++++++++
4 files changed, 261 insertions(+), 9 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig
index 8bf0fa6..212bd3c 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -165,6 +165,9 @@ config HAVE_MIXED_BREAKPOINTS_REGS
config HAVE_USER_RETURN_NOTIFIER
bool
+config USE_COMMON_STRUCT_CLK
+ bool
+
config HAVE_PERF_EVENTS_NMI
bool
help
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 1d37f42..95c49b1 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -3,6 +3,7 @@
*
* Copyright (C) 2004 ARM Limited.
* Written by Deep Blue Solutions Limited.
+ * Copyright (c) 2010 Jeremy Kerr <jeremy.kerr@canonical.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
@@ -11,18 +12,169 @@
#ifndef __LINUX_CLK_H
#define __LINUX_CLK_H
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+
struct device;
-/*
- * The base API.
+#ifdef CONFIG_USE_COMMON_STRUCT_CLK
+
+#define CLK_ATOMIC 0x1
+
+/* If we're using the common struct clk, we define the base clk object here */
+
+/**
+ * struct clk - hardware independent clock structure
+ * @ops: implementation-specific ops for this clock
+ * @enable_count: count of clk_enable() calls active on this clock
+ * @flags: platform-independent flags
+ * @lock: lock for enable/disable or other HW-specific ops
+ *
+ * The base clock object, used by drivers for hardware-independent manipulation
+ * of clock lines. This will be 'subclassed' by device-specific implementations,
+ * which add device-specific data to struct clk. For example:
+ *
+ * struct clk_foo {
+ * struct clk;
+ * [device specific fields]
+ * };
+ *
+ * The clock driver code will manage the device-specific data, and pass
+ * clk_foo.clk to the common clock code. The clock driver will be called
+ * through the @ops callbacks.
+ *
+ * The @lock member provides either a spinlock or a mutex to protect (at least)
+ * @enable_count. The type of lock used will depend on @flags; if CLK_ATOMIC is
+ * set, then the core clock code will use a spinlock, otherwise a mutex. This
+ * lock will be acquired during clk_enable and clk_disable, so for atomic
+ * clocks, these ops callbacks must not sleep.
+ *
+ * The choice of atomic or non-atomic clock depends on how the clock is enabled.
+ * Typically, you'll want to use a non-atomic clock. For clocks that need to be
+ * enabled/disabled in interrupt context, use CLK_ATOMIC. Note that atomic
+ * clocks with parents will typically cascade enable/disable operations to
+ * their parent, so the parent of an atomic clock *must* be atomic too.
+ */
+struct clk {
+ const struct clk_ops *ops;
+ unsigned int enable_count;
+ int flags;
+ union {
+ struct mutex mutex;
+ spinlock_t spinlock;
+ } lock;
+};
+
+/* static initialiser for non-atomic clocks */
+#define INIT_CLK(name, o) { \
+ .ops = &o, \
+ .enable_count = 0, \
+ .flags = 0, \
+ .lock.mutex = __MUTEX_INITIALIZER(name.lock.mutex), \
+}
+
+/* static initialiser for atomic clocks */
+#define INIT_CLK_ATOMIC(name, o) { \
+ .ops = &o, \
+ .enable_count = 0, \
+ .flags = CLK_ATOMIC, \
+ .lock.spinlock = __SPIN_LOCK_UNLOCKED(name.lock.spinlock), \
+}
+
+/**
+ * struct clk_ops - Callback operations for clocks; these are to be provided
+ * by the clock implementation, and will be called by drivers through the clk_*
+ * API.
+ *
+ * @enable: Enable the clock. This must not return until the clock is
+ * generating a valid clock signal, usable by consumer devices.
+ * Called with clk->lock held.
+ *
+ * @disable: Disable the clock. Called with clk->lock held.
+ *
+ * @get: Called by the core clock code when a device driver acquires a
+ * clock via clk_get(). Optional.
+ *
+ * @put: Called by the core clock code when a devices driver releases a
+ * clock via clk_put(). Optional.
+ *
+ * For other callbacks, see the corresponding clk_* functions. Parameters and
+ * return values are passed directly from/to these API functions, or
+ * -ENOSYS (or zero, in the case of clk_get_rate) is returned if the callback
+ * is NULL, see kernel/clk.c for implementation details. All are optional.
*/
+struct clk_ops {
+ int (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+ int (*get)(struct clk *);
+ void (*put)(struct clk *);
+ unsigned long (*get_rate)(struct clk *);
+ long (*round_rate)(struct clk *, unsigned long);
+ int (*set_rate)(struct clk *, unsigned long);
+ int (*set_parent)(struct clk *, struct clk *);
+ struct clk * (*get_parent)(struct clk *);
+};
+static inline void __clk_lock(struct clk *clk)
+{
+ if (clk->flags & CLK_ATOMIC)
+ spin_lock(&clk->lock.spinlock);
+ else
+ mutex_lock(&clk->lock.mutex);
+}
+
+static inline void __clk_unlock(struct clk *clk)
+{
+ if (clk->flags & CLK_ATOMIC)
+ spin_unlock(&clk->lock.spinlock);
+ else
+ mutex_unlock(&clk->lock.mutex);
+}
+
+/**
+ * __clk_get - update clock-specific refcounter
+ *
+ * @clk: The clock to refcount
+ *
+ * Before a clock is returned from clk_get, this function should be called
+ * to update any clock-specific refcounting.
+ *
+ * Returns non-zero on success, zero on failure.
+ *
+ * Drivers should not need this function; it is only needed by the
+ * arch-specific clk_get() implementations.
+ */
+int __clk_get(struct clk *clk);
+
+/**
+ * clk_common_init - initialise a clock for driver usage
+ *
+ * @clk: The clock to initialise
+ *
+ * Used for runtime intialization of clocks; you don't need to call this
+ * if your clock has been (statically) initialized with INIT_CLK.
+ */
+static inline void clk_common_init(struct clk *clk)
+{
+ clk->enable_count = 0;
+ if (clk->flags & CLK_ATOMIC)
+ spin_lock_init(&clk->lock.spinlock);
+ else
+ mutex_init(&clk->lock.mutex);
+}
+
+#else /* !CONFIG_USE_COMMON_STRUCT_CLK */
/*
- * struct clk - an machine class defined object / cookie.
+ * Global clock object, actual structure is declared per-machine
*/
struct clk;
+static inline void clk_common_init(struct clk *clk) { }
+
+#endif /* !CONFIG_USE_COMMON_STRUCT_CLK */
+
/**
* clk_get - lookup and obtain a reference to a clock producer.
* @dev: device for clock "consumer"
@@ -83,12 +235,6 @@ unsigned long clk_get_rate(struct clk *clk);
*/
void clk_put(struct clk *clk);
-
-/*
- * The remaining APIs are optional for machine class support.
- */
-
-
/**
* clk_round_rate - adjust a rate to the exact rate a clock can provide
* @clk: clock source
diff --git a/kernel/Makefile b/kernel/Makefile
index 0b5ff08..01383a0 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -106,6 +106,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
obj-$(CONFIG_PADATA) += padata.o
+obj-$(CONFIG_USE_COMMON_STRUCT_CLK) += clk.o
ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/clk.c b/kernel/clk.c
new file mode 100644
index 0000000..8de8fe3
--- /dev/null
+++ b/kernel/clk.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2010 Canonical Ltd <jeremy.kerr@canonical.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.
+ *
+ * Standard functionality for the common clock API.
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+
+int clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (!clk->ops->enable)
+ return 0;
+
+ __clk_lock(clk);
+ if (!clk->enable_count)
+ ret = clk->ops->enable(clk);
+
+ if (!ret)
+ clk->enable_count++;
+ __clk_unlock(clk);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ if (!clk->ops->disable)
+ return;
+
+ __clk_lock(clk);
+
+ WARN_ON(!clk->enable_count);
+
+ if (!--clk->enable_count)
+ clk->ops->disable(clk);
+
+ __clk_unlock(clk);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk->ops->get_rate)
+ return clk->ops->get_rate(clk);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+int __clk_get(struct clk *clk)
+{
+ if (clk->ops->get)
+ return clk->ops->get(clk);
+ return 1;
+}
+EXPORT_SYMBOL_GPL(__clk_get);
+
+void clk_put(struct clk *clk)
+{
+ if (clk->ops->put)
+ clk->ops->put(clk);
+}
+EXPORT_SYMBOL_GPL(clk_put);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk->ops->round_rate)
+ return clk->ops->round_rate(clk, rate);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk->ops->set_rate)
+ return clk->ops->set_rate(clk, rate);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ if (clk->ops->set_parent)
+ return clk->ops->set_parent(clk, parent);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ if (clk->ops->get_parent)
+ return clk->ops->get_parent(clk);
+ return ERR_PTR(-ENOSYS);
+}
+EXPORT_SYMBOL_GPL(clk_get_parent);
^ permalink raw reply related
* [PATCH 0/2] Common struct clk implementation, v10
From: Jeremy Kerr @ 2011-01-05 3:51 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
These patches are an attempt to allow platforms to share clock code. At
present, the definitions of 'struct clk' are local to platform code,
which makes allocating and initialising cross-platform clock sources
difficult, and makes it impossible to compile a single image containing
support for two ARM platforms with different struct clks.
The two patches are for the architecture-independent kernel code,
introducing the common clk infrastructure. The changelog for the first
patch includes details about the new clock definitions.
As requested by rmk, I've put together a small series of patches
illustrating the usage of the common struct clock on the ARM imx51
platform. These are available in my git tree:
git://kernel.ubuntu.com/jk/dt/linux-2.6
in the clk-common-mx51 branch (clk-common..clk-common-mx51). There is
also a port for versatile (clk-common-versatile) in this tree too.
The approach I've taken with the imx51 port is to temporarly duplicate
the platform-common clock code (ie, for all mxc-based boards) to enable
usage of the common struct clk on one machine (imx51), while leaving the
others as-is. For a proper platform-wide usage of the common struct clk,
we'd be better off doing the whole platform at once. However, mx51 is
the only mxc-based HW I have, hence the duplicated example port.
In the example port, the first change simply converts the mxc's struct
clk to a struct clk_mxc, using the new API. The subsequent patches move
certain clocks to more specific data structures (eg clk_fixed and
clk_pll) where possible.
Also, Yong Shen has contributed a patch to export a tree of clock data
(currently the clock rate and enable_count) through debugfs; this is in
the clk-common-debug branch.
Ben Herrenschmidt is looking at using common struct clk code for powerpc
too, hence the kernel-wide approach.
Many thanks to the following for their input:
* Ben Dooks <ben-linux@fluff.org>
* Baruch Siach <baruch@tkos.co.il>
* Russell King <linux@arm.linux.org.uk>
* Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
* Lorenzo Pieralisi <Lorenzo.Pieralisi@arm.com>
* Vincent Guittot <vincent.guittot@linaro.org>
* Sascha Hauer <s.hauer@pengutronix.de>
Russell - now that we've had a few platforms ported to the common clk
infrastructure, I believe it's ready to merge. If so, do you want this
in the patch tracker? Otherwise, let me know what needs changing.
Cheers,
Jeremy
--
v10:
* comment fixups, from Uwe's review
* added DEFINE_CLK_FIXED
v9:
* comment improvements
* kerneldoc fixups
* add WARN_ON to clk_disable
v8:
* add atomic clocks, and locking wrappers
* expand comments on clk and clk_ops
v7:
* change CLK_INIT to initialise clk->mutex statically
v6:
* fixed up references to 'clk_operations' in the changelog
v5:
* uninline main API, and share definitions with !USE_COMMON_STRUCT_CLK
* add __clk_get
* delay mutex init
* kerneldoc for struct clk
v4:
* use mutex for enable/disable locking
* DEFINE_CLK -> INIT_CLK, and pass the clk name for mutex init
* struct clk_operations -> struct clk_ops
v3:
* do clock usage refcounting in common code
* provide sample port
v2:
* no longer ARM-specific
* use clk_operations
---
Jeremy Kerr (2):
Add a common struct clk
clk: Generic support for fixed-rate clocks
^ permalink raw reply
* [RFC 1/5] ARM: P2V: separate PHYS_OFFSET from platform definitions
From: viresh kumar @ 2011-01-05 3:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <E1PaDOb-00023Z-CR@rmk-PC.arm.linux.org.uk>
On 01/05/2011 01:52 AM, Russell King - ARM Linux wrote:
> This uncouple PHYS_OFFSET from the platform definitions, thereby
> facilitating run-time computation of the physical memory offset.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
>
> diff --git a/arch/arm/plat-spear/include/plat/memory.h b/arch/arm/plat-spear/include/plat/memory.h
> index 27a4aba..7e3599e 100644
> --- a/arch/arm/plat-spear/include/plat/memory.h
> +++ b/arch/arm/plat-spear/include/plat/memory.h
> @@ -15,6 +15,6 @@
> #define __PLAT_MEMORY_H
>
> /* Physical DRAM offset */
> -#define PHYS_OFFSET UL(0x00000000)
> +#define PLAT_PHYS_OFFSET UL(0x00000000)
>
> #endif /* __PLAT_MEMORY_H */
Acked-by: Viresh Kumar <viresh.kumar@st.com>
--
viresh
^ permalink raw reply
* [PATCH 1/2] Add a common struct clk
From: Jeremy Kerr @ 2011-01-05 3:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294197535.808797.65909636853.0.gpush@pororo>
We currently have ~21 definitions of struct clk in the ARM architecture,
each defined on a per-platform basis. This makes it difficult to define
platform- (or architecture-) independent clock sources without making
assumptions about struct clk, and impossible to compile two
platforms with different struct clks into a single image.
This change is an effort to unify struct clk where possible, by defining
a common struct clk, containing a set of clock operations. Different
clock implementations can set their own operations, and have a standard
interface for generic code. The callback interface is exposed to the
kernel proper, while the clock implementations only need to be seen by
the platform internals.
This allows us to share clock code among platforms, and makes it
possible to dynamically create clock devices in platform-independent
code.
Platforms can enable the generic struct clock through
CONFIG_USE_COMMON_STRUCT_CLK. In this case, the clock infrastructure
consists of a common struct clk:
struct clk {
const struct clk_ops *ops;
unsigned int enable_count;
int flags;
union {
struct mutex mutex;
spinlock_t spinlock;
} lock;
};
And a set of clock operations (defined per type of clock):
struct clk_ops {
int (*enable)(struct clk *);
void (*disable)(struct clk *);
unsigned long (*get_rate)(struct clk *);
[...]
};
To define a hardware-specific clock, machine code can "subclass" the
struct clock into a new struct (adding any device-specific data), and
provide a set of operations:
struct clk_foo {
struct clk clk;
void __iomem *some_register;
};
struct clk_ops clk_foo_ops = {
.get_rate = clk_foo_get_rate,
};
The common clock definitions are based on a development patch from Ben
Herrenschmidt <benh@kernel.crashing.org>.
Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
Acked-by: Paulius Zaleckas <paulius.zaleckas@gmail.com>
---
arch/Kconfig | 3
include/linux/clk.h | 164 +++++++++++++++++++++++++++++++++++++++++---
kernel/Makefile | 1
kernel/clk.c | 102 +++++++++++++++++++++++++++
4 files changed, 261 insertions(+), 9 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig
index 8bf0fa6..212bd3c 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -165,6 +165,9 @@ config HAVE_MIXED_BREAKPOINTS_REGS
config HAVE_USER_RETURN_NOTIFIER
bool
+config USE_COMMON_STRUCT_CLK
+ bool
+
config HAVE_PERF_EVENTS_NMI
bool
help
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 1d37f42..95c49b1 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -3,6 +3,7 @@
*
* Copyright (C) 2004 ARM Limited.
* Written by Deep Blue Solutions Limited.
+ * Copyright (c) 2010 Jeremy Kerr <jeremy.kerr@canonical.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
@@ -11,18 +12,169 @@
#ifndef __LINUX_CLK_H
#define __LINUX_CLK_H
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+
struct device;
-/*
- * The base API.
+#ifdef CONFIG_USE_COMMON_STRUCT_CLK
+
+#define CLK_ATOMIC 0x1
+
+/* If we're using the common struct clk, we define the base clk object here */
+
+/**
+ * struct clk - hardware independent clock structure
+ * @ops: implementation-specific ops for this clock
+ * @enable_count: count of clk_enable() calls active on this clock
+ * @flags: platform-independent flags
+ * @lock: lock for enable/disable or other HW-specific ops
+ *
+ * The base clock object, used by drivers for hardware-independent manipulation
+ * of clock lines. This will be 'subclassed' by device-specific implementations,
+ * which add device-specific data to struct clk. For example:
+ *
+ * struct clk_foo {
+ * struct clk;
+ * [device specific fields]
+ * };
+ *
+ * The clock driver code will manage the device-specific data, and pass
+ * clk_foo.clk to the common clock code. The clock driver will be called
+ * through the @ops callbacks.
+ *
+ * The @lock member provides either a spinlock or a mutex to protect (at least)
+ * @enable_count. The type of lock used will depend on @flags; if CLK_ATOMIC is
+ * set, then the core clock code will use a spinlock, otherwise a mutex. This
+ * lock will be acquired during clk_enable and clk_disable, so for atomic
+ * clocks, these ops callbacks must not sleep.
+ *
+ * The choice of atomic or non-atomic clock depends on how the clock is enabled.
+ * Typically, you'll want to use a non-atomic clock. For clocks that need to be
+ * enabled/disabled in interrupt context, use CLK_ATOMIC. Note that atomic
+ * clocks with parents will typically cascade enable/disable operations to
+ * their parent, so the parent of an atomic clock *must* be atomic too.
+ */
+struct clk {
+ const struct clk_ops *ops;
+ unsigned int enable_count;
+ int flags;
+ union {
+ struct mutex mutex;
+ spinlock_t spinlock;
+ } lock;
+};
+
+/* static initialiser for non-atomic clocks */
+#define INIT_CLK(name, o) { \
+ .ops = &o, \
+ .enable_count = 0, \
+ .flags = 0, \
+ .lock.mutex = __MUTEX_INITIALIZER(name.lock.mutex), \
+}
+
+/* static initialiser for atomic clocks */
+#define INIT_CLK_ATOMIC(name, o) { \
+ .ops = &o, \
+ .enable_count = 0, \
+ .flags = CLK_ATOMIC, \
+ .lock.spinlock = __SPIN_LOCK_UNLOCKED(name.lock.spinlock), \
+}
+
+/**
+ * struct clk_ops - Callback operations for clocks; these are to be provided
+ * by the clock implementation, and will be called by drivers through the clk_*
+ * API.
+ *
+ * @enable: Enable the clock. This must not return until the clock is
+ * generating a valid clock signal, usable by consumer devices.
+ * Called with clk->lock held.
+ *
+ * @disable: Disable the clock. Called with clk->lock held.
+ *
+ * @get: Called by the core clock code when a device driver acquires a
+ * clock via clk_get(). Optional.
+ *
+ * @put: Called by the core clock code when a devices driver releases a
+ * clock via clk_put(). Optional.
+ *
+ * For other callbacks, see the corresponding clk_* functions. Parameters and
+ * return values are passed directly from/to these API functions, or
+ * -ENOSYS (or zero, in the case of clk_get_rate) is returned if the callback
+ * is NULL, see kernel/clk.c for implementation details. All are optional.
*/
+struct clk_ops {
+ int (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+ int (*get)(struct clk *);
+ void (*put)(struct clk *);
+ unsigned long (*get_rate)(struct clk *);
+ long (*round_rate)(struct clk *, unsigned long);
+ int (*set_rate)(struct clk *, unsigned long);
+ int (*set_parent)(struct clk *, struct clk *);
+ struct clk * (*get_parent)(struct clk *);
+};
+static inline void __clk_lock(struct clk *clk)
+{
+ if (clk->flags & CLK_ATOMIC)
+ spin_lock(&clk->lock.spinlock);
+ else
+ mutex_lock(&clk->lock.mutex);
+}
+
+static inline void __clk_unlock(struct clk *clk)
+{
+ if (clk->flags & CLK_ATOMIC)
+ spin_unlock(&clk->lock.spinlock);
+ else
+ mutex_unlock(&clk->lock.mutex);
+}
+
+/**
+ * __clk_get - update clock-specific refcounter
+ *
+ * @clk: The clock to refcount
+ *
+ * Before a clock is returned from clk_get, this function should be called
+ * to update any clock-specific refcounting.
+ *
+ * Returns non-zero on success, zero on failure.
+ *
+ * Drivers should not need this function; it is only needed by the
+ * arch-specific clk_get() implementations.
+ */
+int __clk_get(struct clk *clk);
+
+/**
+ * clk_common_init - initialise a clock for driver usage
+ *
+ * @clk: The clock to initialise
+ *
+ * Used for runtime intialization of clocks; you don't need to call this
+ * if your clock has been (statically) initialized with INIT_CLK.
+ */
+static inline void clk_common_init(struct clk *clk)
+{
+ clk->enable_count = 0;
+ if (clk->flags & CLK_ATOMIC)
+ spin_lock_init(&clk->lock.spinlock);
+ else
+ mutex_init(&clk->lock.mutex);
+}
+
+#else /* !CONFIG_USE_COMMON_STRUCT_CLK */
/*
- * struct clk - an machine class defined object / cookie.
+ * Global clock object, actual structure is declared per-machine
*/
struct clk;
+static inline void clk_common_init(struct clk *clk) { }
+
+#endif /* !CONFIG_USE_COMMON_STRUCT_CLK */
+
/**
* clk_get - lookup and obtain a reference to a clock producer.
* @dev: device for clock "consumer"
@@ -83,12 +235,6 @@ unsigned long clk_get_rate(struct clk *clk);
*/
void clk_put(struct clk *clk);
-
-/*
- * The remaining APIs are optional for machine class support.
- */
-
-
/**
* clk_round_rate - adjust a rate to the exact rate a clock can provide
* @clk: clock source
diff --git a/kernel/Makefile b/kernel/Makefile
index 0b5ff08..01383a0 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -106,6 +106,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
obj-$(CONFIG_PADATA) += padata.o
+obj-$(CONFIG_USE_COMMON_STRUCT_CLK) += clk.o
ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/clk.c b/kernel/clk.c
new file mode 100644
index 0000000..8de8fe3
--- /dev/null
+++ b/kernel/clk.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2010 Canonical Ltd <jeremy.kerr@canonical.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.
+ *
+ * Standard functionality for the common clock API.
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+
+int clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (!clk->ops->enable)
+ return 0;
+
+ __clk_lock(clk);
+ if (!clk->enable_count)
+ ret = clk->ops->enable(clk);
+
+ if (!ret)
+ clk->enable_count++;
+ __clk_unlock(clk);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ if (!clk->ops->disable)
+ return;
+
+ __clk_lock(clk);
+
+ WARN_ON(!clk->enable_count);
+
+ if (!--clk->enable_count)
+ clk->ops->disable(clk);
+
+ __clk_unlock(clk);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk->ops->get_rate)
+ return clk->ops->get_rate(clk);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+int __clk_get(struct clk *clk)
+{
+ if (clk->ops->get)
+ return clk->ops->get(clk);
+ return 1;
+}
+EXPORT_SYMBOL_GPL(__clk_get);
+
+void clk_put(struct clk *clk)
+{
+ if (clk->ops->put)
+ clk->ops->put(clk);
+}
+EXPORT_SYMBOL_GPL(clk_put);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk->ops->round_rate)
+ return clk->ops->round_rate(clk, rate);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk->ops->set_rate)
+ return clk->ops->set_rate(clk, rate);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ if (clk->ops->set_parent)
+ return clk->ops->set_parent(clk, parent);
+ return -ENOSYS;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ if (clk->ops->get_parent)
+ return clk->ops->get_parent(clk);
+ return ERR_PTR(-ENOSYS);
+}
+EXPORT_SYMBOL_GPL(clk_get_parent);
^ permalink raw reply related
* [PATCH 0/2] Common struct clk implementation, v10
From: Jeremy Kerr @ 2011-01-05 3:18 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
These patches are an attempt to allow platforms to share clock code. At
present, the definitions of 'struct clk' are local to platform code,
which makes allocating and initialising cross-platform clock sources
difficult, and makes it impossible to compile a single image containing
support for two ARM platforms with different struct clks.
The two patches are for the architecture-independent kernel code,
introducing the common clk infrastructure. The changelog for the first
patch includes details about the new clock definitions.
As requested by rmk, I've put together a small series of patches
illustrating the usage of the common struct clock on the ARM imx51
platform. These are available in my git tree:
git://kernel.ubuntu.com/jk/dt/linux-2.6
in the clk-common-mx51 branch (clk-common..clk-common-mx51). There is
also a port for versatile (clk-common-versatile) in this tree too.
The approach I've taken with the imx51 port is to temporarly duplicate
the platform-common clock code (ie, for all mxc-based boards) to enable
usage of the common struct clk on one machine (imx51), while leaving the
others as-is. For a proper platform-wide usage of the common struct clk,
we'd be better off doing the whole platform at once. However, mx51 is
the only mxc-based HW I have, hence the duplicated example port.
In the example port, the first change simply converts the mxc's struct
clk to a struct clk_mxc, using the new API. The subsequent patches move
certain clocks to more specific data structures (eg clk_fixed and
clk_pll) where possible.
Also, Yong Shen has contributed a patch to export a tree of clock data
(currently the clock rate and enable_count) through debugfs; this is in
the clk-common-debug branch.
Ben Herrenschmidt is looking at using common struct clk code for powerpc
too, hence the kernel-wide approach.
Many thanks to the following for their input:
* Ben Dooks <ben-linux@fluff.org>
* Baruch Siach <baruch@tkos.co.il>
* Russell King <linux@arm.linux.org.uk>
* Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
* Lorenzo Pieralisi <Lorenzo.Pieralisi@arm.com>
* Vincent Guittot <vincent.guittot@linaro.org>
* Sascha Hauer <s.hauer@pengutronix.de>
Russell - now that we've had a few platforms ported to the common clk
infrastructure, I believe it's ready to merge. If so, do you want this
in the patch tracker? Otherwise, let me know what needs changing.
Cheers,
Jeremy
--
v10:
* comment fixups, from Uwe's review
* added DEFINE_CLK_FIXED
v9:
* comment improvements
* kerneldoc fixups
* add WARN_ON to clk_disable
v8:
* add atomic clocks, and locking wrappers
* expand comments on clk and clk_ops
v7:
* change CLK_INIT to initialise clk->mutex statically
v6:
* fixed up references to 'clk_operations' in the changelog
v5:
* uninline main API, and share definitions with !USE_COMMON_STRUCT_CLK
* add __clk_get
* delay mutex init
* kerneldoc for struct clk
v4:
* use mutex for enable/disable locking
* DEFINE_CLK -> INIT_CLK, and pass the clk name for mutex init
* struct clk_operations -> struct clk_ops
v3:
* do clock usage refcounting in common code
* provide sample port
v2:
* no longer ARM-specific
* use clk_operations
---
Jeremy Kerr (2):
Add a common struct clk
clk: Generic support for fixed-rate clocks
^ permalink raw reply
* [PATCH 2/2] clk: Generic support for fixed-rate clocks
From: Jeremy Kerr @ 2011-01-05 3:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294197535.808797.65909636853.0.gpush@pororo>
Since most platforms will need a fixed-rate clock, add one. This will
also serve as a basic example of an implementation of struct clk.
Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
---
include/linux/clk.h | 16 ++++++++++++++++
kernel/clk.c | 14 ++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 95c49b1..6cef9fe 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -164,6 +164,22 @@ static inline void clk_common_init(struct clk *clk)
mutex_init(&clk->lock.mutex);
}
+/* Simple fixed-rate clock */
+struct clk_fixed {
+ struct clk clk;
+ unsigned long rate;
+};
+
+extern struct clk_ops clk_fixed_ops;
+
+#define INIT_CLK_FIXED(name, r) { \
+ .clk = INIT_CLK(name.clk, clk_fixed_ops), \
+ .rate = (r) \
+}
+
+#define DEFINE_CLK_FIXED(name, r) \
+ struct clk_fixed name = INIT_CLK_FIXED(name, r)
+
#else /* !CONFIG_USE_COMMON_STRUCT_CLK */
/*
diff --git a/kernel/clk.c b/kernel/clk.c
index 8de8fe3..6c38cc0 100644
--- a/kernel/clk.c
+++ b/kernel/clk.c
@@ -100,3 +100,17 @@ struct clk *clk_get_parent(struct clk *clk)
return ERR_PTR(-ENOSYS);
}
EXPORT_SYMBOL_GPL(clk_get_parent);
+
+/* clk_fixed support */
+
+#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
+
+static unsigned long clk_fixed_get_rate(struct clk *clk)
+{
+ return to_clk_fixed(clk)->rate;
+}
+
+struct clk_ops clk_fixed_ops = {
+ .get_rate = clk_fixed_get_rate,
+};
+EXPORT_SYMBOL_GPL(clk_fixed_ops);
^ permalink raw reply related
* [PATCH v3 1/2] ARM i.MX53: Some bug fix about MX53 MSL code
From: Yong Shen @ 2011-01-05 2:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTimD_HteeyhdHcGiJU6jashyPfoLGP_bWkWAj0Ap@mail.gmail.com>
Hi Fabio,
:->. my bad. Since my network link is pretty slow, I normally update
every git repo at night, which is why I missed it.
Thanks
Yong
On Wed, Jan 5, 2011 at 7:32 AM, Fabio Estevam <festevam@gmail.com> wrote:
> Yong,
>
> On Tue, Jan 4, 2011 at 12:41 PM, Yong Shen <yong.shen@linaro.org> wrote:
>> Hi there,
>>
>> Are there any more comments?
>> Because of the time difference, the review process is longer than it
>> should be. If no more comments, I am going to ask for merge, so more
>> works can be carry on based on this.
>
> Looks like you haven?t checked Sascha?s tree:
> http://git.pengutronix.de/?p=imx/linux-2.6.git;a=shortlog;h=refs/heads/imx-for-2.6.38
>
> The patch is there ;-)
>
> Regards,
>
> Fabio Estevam
>
^ permalink raw reply
* [PATCH 6/6] Fix eseries compilation if w100fb is not compiled in kernel
From: Dmitry Eremin-Solenikov @ 2011-01-05 2:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294193110-23958-1-git-send-email-dbaryshkov@gmail.com>
e800_tg_change depends on w100fb_gpio_read/write API which is only present
if w100fb is compiled in kernel.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Cc: Ian Molton <ian@mnementh.co.uk>
---
arch/arm/mach-pxa/eseries.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index b25690c..ed2c157 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -829,6 +829,7 @@ static struct w100_mem_info e800_w100_mem_info = {
static void e800_tg_change(struct w100fb_par *par)
{
+#ifdef FB_W100
unsigned long tmp;
tmp = w100fb_gpio_read(W100_GPIO_PORT_A);
@@ -837,6 +838,7 @@ static void e800_tg_change(struct w100fb_par *par)
else
tmp &= ~0x100;
w100fb_gpio_write(W100_GPIO_PORT_A, tmp);
+#endif
}
static struct w100_tg_info e800_tg_info = {
--
1.7.2.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox