* [PATCH v2] gpio: pl061: add DT binding support
From: Rob Herring @ 2011-09-22 23:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1313011906-24161-1-git-send-email-robherring2@gmail.com>
Grant,
On 08/10/2011 04:31 PM, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> This adds devicetree binding support to the ARM pl061 driver removing the
> platform_data dependency. When DT binding is used, the gpio numbering is
> assigned dynamically. For now, interrupts are not supported with DT until
> irqdomains learn dynamic irq assignment.
>
> Rather than add another case of -1, updating the driver to use NO_IRQ.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> ---
Ping. Any comments on this?
Rob
>
> v2:
> - Add other -1 to NO_IRQ conversions
> - Drop DT irq support for now
>
> drivers/gpio/gpio-pl061.c | 31 +++++++++++++++++++++----------
> include/linux/amba/pl061.h | 3 +--
> 2 files changed, 22 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
> index 2c5a18f..093c90b 100644
> --- a/drivers/gpio/gpio-pl061.c
> +++ b/drivers/gpio/gpio-pl061.c
> @@ -118,7 +118,7 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
> {
> struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
>
> - if (chip->irq_base == (unsigned) -1)
> + if (chip->irq_base == NO_IRQ)
> return -EINVAL;
>
> return chip->irq_base + offset;
> @@ -246,6 +246,18 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> if (chip == NULL)
> return -ENOMEM;
>
> + pdata = dev->dev.platform_data;
> + if (pdata) {
> + chip->gc.base = pdata->gpio_base;
> + chip->irq_base = pdata->irq_base;
> + } else if (dev->dev.of_node) {
> + chip->gc.base = -1;
> + chip->irq_base = NO_IRQ;
> + } else {
> + ret = -ENODEV;
> + goto free_mem;
> + }
> +
> if (!request_mem_region(dev->res.start,
> resource_size(&dev->res), "pl061")) {
> ret = -EBUSY;
> @@ -267,14 +279,11 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> chip->gc.get = pl061_get_value;
> chip->gc.set = pl061_set_value;
> chip->gc.to_irq = pl061_to_irq;
> - chip->gc.base = pdata->gpio_base;
> chip->gc.ngpio = PL061_GPIO_NR;
> chip->gc.label = dev_name(&dev->dev);
> chip->gc.dev = &dev->dev;
> chip->gc.owner = THIS_MODULE;
>
> - chip->irq_base = pdata->irq_base;
> -
> ret = gpiochip_add(&chip->gc);
> if (ret)
> goto iounmap;
> @@ -283,7 +292,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> * irq_chip support
> */
>
> - if (chip->irq_base == (unsigned) -1)
> + if (chip->irq_base == NO_IRQ)
> return 0;
>
> writeb(0, chip->base + GPIOIE); /* disable irqs */
> @@ -307,11 +316,13 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> list_add(&chip->list, chip_list);
>
> for (i = 0; i < PL061_GPIO_NR; i++) {
> - if (pdata->directions & (1 << i))
> - pl061_direction_output(&chip->gc, i,
> - pdata->values & (1 << i));
> - else
> - pl061_direction_input(&chip->gc, i);
> + if (pdata) {
> + if (pdata->directions & (1 << i))
> + pl061_direction_output(&chip->gc, i,
> + pdata->values & (1 << i));
> + else
> + pl061_direction_input(&chip->gc, i);
> + }
>
> irq_set_chip_and_handler(i + chip->irq_base, &pl061_irqchip,
> handle_simple_irq);
> diff --git a/include/linux/amba/pl061.h b/include/linux/amba/pl061.h
> index 5ddd9ad..2412af9 100644
> --- a/include/linux/amba/pl061.h
> +++ b/include/linux/amba/pl061.h
> @@ -7,8 +7,7 @@ struct pl061_platform_data {
> unsigned gpio_base;
>
> /* number of the first IRQ.
> - * If the IRQ functionality in not desired this must be set to
> - * (unsigned) -1.
> + * If the IRQ functionality in not desired this must be set to NO_IRQ.
> */
> unsigned irq_base;
>
^ permalink raw reply
* [PATCH 02/10] cpufreq: OMAP: Add SMP support for OMAP4+
From: Kevin Hilman @ 2011-09-22 23:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316725648-26710-3-git-send-email-khilman@ti.com>
Kevin Hilman <khilman@ti.com> writes:
> From: Russell King <rmk+kernel@arm.linux.org.uk>
>
> On OMAP SMP configuartion, both processors share the voltage
> and clock. So both CPUs needs to be scaled together and hence
> needs software co-ordination.
[...]
> diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
> index a6b2be7..f9b4c4d 100644
> --- a/drivers/cpufreq/omap-cpufreq.c
> +++ b/drivers/cpufreq/omap-cpufreq.c
> @@ -23,6 +23,7 @@
> #include <linux/clk.h>
> #include <linux/io.h>
> #include <linux/opp.h>
> +#include <linux/cpu.h>
>
> #include <asm/system.h>
> #include <asm/smp_plat.h>
Thanks to checkpatch, I blindly removed an "#include <asm/cpu.h>" here
without re-testing. Turns out it was important.
Added it back, and updated the version available in my
for_3.2/omap-cpufreq branch.
Kevin
^ permalink raw reply
* [PATCH v2 0/7] Add a generic struct clk
From: Turquette, Mike @ 2011-09-22 23:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316730422-20027-1-git-send-email-mturquette@ti.com>
On Thu, Sep 22, 2011 at 3:26 PM, Mike Turquette <mturquette@ti.com> wrote:
> Hi all,
>
> The goal of this series is to provide a cross-platform clock framework
> that platforms can use to model their clock trees and perform common
> operations on them. ?Currently everyone re-invents their own clock tree
> inside platform code which makes it impossible for drivers to use the
> clock APIs safely across many platforms and for distro's to compile
> multi-platform kernels which all redefine struct clk and its operations.
>
> This is the second version of the common clock patches which were
> originally posted by Jeremy Kerr and then re-posted with some additional
> patches by Mark Brown. ?Mark's re-post didn't have any changes done to
> the original four patches from Jeremy which is why this series is "v2".
>
> The changes in this series are minimal: I've folded in some of Mark's
> fixes and most of the comments posted to his series as well as rebasing
> on top of v3.1-rc7. ?The design and functionality hasn't changed much
> since Jeremy posted v1 of this series. ?Propagating the rate change up
> to the parent has been removed from clk_set_rate since that needs some
> more thought. ?I also dropped Mark's change to append a device's name to
> a clk name since device tree might solve this neatly. ?Again more
> discussion around that would be good.
For convenience these patches can be found at:
git://git.linaro.org/people/mturquette/linux.git
v3.1-rc7-clkv2
Regards,
Mike
^ permalink raw reply
* [PATCH v7 00/26] gpio/omap: driver cleanup and fixes
From: Kevin Hilman @ 2011-09-22 23:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1315918979-26173-1-git-send-email-tarun.kanti@ti.com>
Tarun Kanti DebBarma <tarun.kanti@ti.com> writes:
> This series is continuation of cleanup of OMAP GPIO driver and fixes.
> The cleanup include getting rid of cpu_is_* checks wherever possible,
> use of gpio_bank list instead of static array, use of unique platform
> specific value associated data member to OMAP platforms to avoid
> cpu_is_* checks. The series also include PM runtime support.*
PER is still not hitting retention for me on 34xx/n900 when GPIOs have
debounce enabled. Disabling debounce in the board file makes it work.
[...]
> - Add dbclk aliases for all GPIO modules. Without this, GPIO modules were not
> getting the correct clock handle to enable/disable debounec clock.
This isn't right. hwmod should already be adding aliases for the
optional clocks.
After debugging this myself a bit, here's what I think may be going on.
This may not be the only problem but here's at least one of them.
First, debounce clocks are disabled in the runtime_suspend callback.
When a GPIO is freed and it's the last one in the bank, bank->mod_usage
goes to zero.
After that, pm_runtime_put_sync() is called, which will trigger the
driver's ->runtime_suspend callback. The ->runtime_suspend() callback
checks bank->mod_usage as well, and if zero, doesn't do anything
(notably, it doesn't disable debounce clocks.)
Kevin
^ permalink raw reply
* [PATCH] ARM: futex: fix clobbering oldval
From: mhban @ 2011-09-23 0:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110922172653.GH13572@e102144-lin.cambridge.arm.com>
On Thu, 2011-09-22 at 18:26 +0100, Will Deacon wrote:
> Hi,
>
> On Thu, Sep 22, 2011 at 03:53:35AM +0100, mhban wrote:
> > This patch fixes clobbering oldval bug. oldval should be preserved for next
> > compare operation.
> >
> > Change-Id: I2a63bc1bdb8de330eb9e1ac02d7da1f77e6e8c3c
> > Signed-off-by: Minho Ban <mhban@samsung.com>
>
> It would have been nice to have been CC'd on this...
Will not miss next time. Thanks.
>
> I ran LTP tests on this, so I'm surprised that this was broken (the tests
> passed). Well spotted anyway!
>
> > ---
> > arch/arm/include/asm/futex.h | 6 +++---
> > 1 files changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h
> > index d2d733c..b0f2e8e 100644
> > --- a/arch/arm/include/asm/futex.h
> > +++ b/arch/arm/include/asm/futex.h
> > @@ -30,14 +30,14 @@
> > __asm__ __volatile__( \
> > "1: ldrex %1, [%2]\n" \
> > " " insn "\n" \
> > - "2: strex %1, %0, [%2]\n" \
> > - " teq %1, #0\n" \
> > + "2: strex r5, %0, [%2]\n" \
> > + " teq r5, #0\n" \
> > " bne 1b\n" \
> > " mov %0, #0\n" \
> > __futex_atomic_ex_table("%4") \
> > : "=&r" (ret), "=&r" (oldval) \
> > : "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \
> > - : "cc", "memory")
> > + : "r5", "cc", "memory")
>
> You shouldn't reference r5 directly here, but due to the way the futex code
> is laid out, you can't add an extra output operand without converting the
> code to use named arguments.
>
> I'll post a patch to do that.
>
> Will
I'm not familiar with gcc inline, thanks for pointing it out.
BTW, my last name is Ban not Ben.
Minho
^ permalink raw reply
* [PATCH v2 1/3] TI81XX: Prepare for addition of TI814X support
From: Pedanekar, Hemant @ 2011-09-23 0:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110922182113.GU2937@atomide.com>
Tony Lindgren wrote on Thursday, September 22, 2011 11:51 PM:
> * Pedanekar, Hemant <hemantp@ti.com> [110921 17:00]:
>> Tony Lindgren wrote on Thursday, September 22, 2011 2:11 AM:
>>
>>> * Hemant Pedanekar <hemantp@ti.com> [110921 10:05]:
>>>> --- a/arch/arm/mach-omap2/board-ti8168evm.c
>>>> +++ b/arch/arm/mach-omap2/board-ti8168evm.c
>>>> @@ -37,16 +37,16 @@ static void __init ti8168_evm_init(void)
>>>>
>>>> static void __init ti8168_evm_map_io(void)
>>>> {
>>>> - omap2_set_globals_ti816x();
>>>> - omapti816x_map_common_io();
>>>> + omap2_set_globals_ti81xx();
>>>> + omapti81xx_map_common_io();
>>>> }
>>>>
>>>> MACHINE_START(TI8168EVM, "ti8168evm")
>>>> /* Maintainer: Texas Instruments */
>>>> .atag_offset = 0x100,
>>>> .map_io = ti8168_evm_map_io,
>>>> - .init_early = ti816x_init_early,
>>>> - .init_irq = ti816x_init_irq,
>>>> + .init_early = ti81xx_init_early,
>>>> + .init_irq = ti81xx_init_irq,
>>>> .timer = &omap3_timer,
>>>> .init_machine = ti8168_evm_init,
>>>> MACHINE_END
>>>
>>> Looks like you still need a minor rebase on the current cleanup
>>> branch as the ti8668_evm_map_io is no longer needed. The cleanup
>>> branch already has Paul's CHIP_IS removal, so that should be trivial.
>>>
>>
>> Tony,
>> Can you please clarify? Do we not need ti8168_evm_map_io() for global data
>> initianlization and io init? Or, as you mentioned in comment on 3/3 of the
>> series, do you mean to rename this with ti81xx and move to common.c?
>
> Yes just have a generic one in common.c should be enough. Sorry I thought
> that was already done, but looks like it was only done for omap3_map_io.
>
>>> Ideally the rename patch would be separate without any functional
>>> changes, maybe you can move the changes and additions to the next patch?
>>>
>>> Tony
>>
>> If the above understanding is correct, then I will just have to rename+move
>> ti8168_evm_map_io() so the change can still be in this patch, right? Or are
>> You referring to any other part which should not be in this patch?
>
> Yes it's OK to keep it in this patch.
>
> Tony
Thanks. I will send updated version.
Hemant
^ permalink raw reply
* [PATCH 24/55] SCSI: irq: Remove IRQF_DISABLED
From: Jack Wang @ 2011-09-23 1:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316681962-8217-25-git-send-email-yong.zhang0@gmail.com>
Acked-by: Jack Wang <jack_wang@usish.com>
[PATCH 24/55] SCSI: irq: Remove IRQF_DISABLED
>
> Since commit [e58aa3d2: genirq: Run irq handlers with interrupts
disabled],
> We run all interrupt handlers with interrupts disabled
> and we even check and yell when an interrupt handler
> returns with interrupts enabled (see commit [b738a50a:
> genirq: Warn when handler enables interrupts]).
>
> So now this flag is a NOOP and can be removed.
>
> Signed-off-by: Yong Zhang <yong.zhang0@gmail.com>
> ---
> drivers/scsi/NCR5380.c | 2 +-
> drivers/scsi/aacraid/rx.c | 2 +-
> drivers/scsi/aacraid/sa.c | 2 +-
> drivers/scsi/aacraid/src.c | 2 +-
> drivers/scsi/aha152x.c | 4 ++--
> drivers/scsi/aic7xxx_old.c | 2 +-
> drivers/scsi/arm/acornscsi.c | 2 +-
> drivers/scsi/arm/cumana_1.c | 2 +-
> drivers/scsi/arm/cumana_2.c | 2 +-
> drivers/scsi/arm/powertec.c | 2 +-
> drivers/scsi/dtc.c | 2 +-
> drivers/scsi/eata.c | 2 +-
> drivers/scsi/eata_pio.c | 4 ++--
> drivers/scsi/g_NCR5380.c | 2 +-
> drivers/scsi/gdth.c | 6 +++---
> drivers/scsi/hpsa.c | 4 ++--
> drivers/scsi/ibmvscsi/ibmvstgt.c | 2 +-
> drivers/scsi/in2000.c | 2 +-
> drivers/scsi/initio.c | 2 +-
> drivers/scsi/pas16.c | 2 +-
> drivers/scsi/pm8001/pm8001_init.c | 4 +---
> drivers/scsi/t128.c | 2 +-
> drivers/scsi/u14-34f.c | 2 +-
> drivers/scsi/wd7000.c | 2 +-
> 24 files changed, 29 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
> index 165e4dd86..9f6de17 100644
> --- a/drivers/scsi/NCR5380.c
> +++ b/drivers/scsi/NCR5380.c
> @@ -584,7 +584,7 @@ static int __init __maybe_unused
NCR5380_probe_irq(struct
> Scsi_Host *instance,
> NCR5380_setup(instance);
>
> for (trying_irqs = i = 0, mask = 1; i < 16; ++i, mask <<= 1)
> - if ((mask & possible) && (request_irq(i, &probe_intr,
IRQF_DISABLED,
> "NCR-probe", NULL) == 0))
> + if ((mask & possible) && (request_irq(i, &probe_intr, 0,
"NCR-probe",
> NULL) == 0))
> trying_irqs |= mask;
>
> timeout = jiffies + (250 * HZ / 1000);
> diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
> index ce530f1..d1e2a2a 100644
> --- a/drivers/scsi/aacraid/rx.c
> +++ b/drivers/scsi/aacraid/rx.c
> @@ -645,7 +645,7 @@ int _aac_rx_init(struct aac_dev *dev)
> aac_adapter_comm(dev, dev->comm_interface);
> dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
> if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
> - IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {
> + IRQF_SHARED, "aacraid", dev) < 0) {
> if (dev->msi)
> pci_disable_msi(dev->pdev);
> printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
> diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
> index e5d4457..c3e1f6b 100644
> --- a/drivers/scsi/aacraid/sa.c
> +++ b/drivers/scsi/aacraid/sa.c
> @@ -386,7 +386,7 @@ int aac_sa_init(struct aac_dev *dev)
> if(aac_init_adapter(dev) == NULL)
> goto error_irq;
> if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
> - IRQF_SHARED|IRQF_DISABLED,
> + IRQF_SHARED,
> "aacraid", (void *)dev ) < 0) {
> printk(KERN_WARNING "%s%d: Interrupt unavailable.\n",
> name, instance);
> diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
> index 957595a..68374e4 100644
> --- a/drivers/scsi/aacraid/src.c
> +++ b/drivers/scsi/aacraid/src.c
> @@ -565,7 +565,7 @@ int aac_src_init(struct aac_dev *dev)
> dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
>
> if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
> - IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {
> + IRQF_SHARED, "aacraid", dev) < 0) {
>
> if (dev->msi)
> pci_disable_msi(dev->pdev);
> diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
> index f17c92c..46e7a53 100644
> --- a/drivers/scsi/aha152x.c
> +++ b/drivers/scsi/aha152x.c
> @@ -858,7 +858,7 @@ struct Scsi_Host *aha152x_probe_one(struct
aha152x_setup
> *setup)
> SETPORT(SIMODE0, 0);
> SETPORT(SIMODE1, 0);
>
> - if( request_irq(shpnt->irq, swintr, IRQF_DISABLED|IRQF_SHARED,
> "aha152x", shpnt) ) {
> + if( request_irq(shpnt->irq, swintr, IRQF_SHARED, "aha152x", shpnt) )
{
> printk(KERN_ERR "aha152x%d: irq %d busy.\n", shpnt->host_no,
> shpnt->irq);
> goto out_host_put;
> }
> @@ -892,7 +892,7 @@ struct Scsi_Host *aha152x_probe_one(struct
aha152x_setup
> *setup)
> SETPORT(SSTAT0, 0x7f);
> SETPORT(SSTAT1, 0xef);
>
> - if ( request_irq(shpnt->irq, intr, IRQF_DISABLED|IRQF_SHARED,
"aha152x",
> shpnt) ) {
> + if ( request_irq(shpnt->irq, intr, IRQF_SHARED, "aha152x", shpnt) )
{
> printk(KERN_ERR "aha152x%d: failed to reassign irq %d.\n",
> shpnt->host_no, shpnt->irq);
> goto out_host_put;
> }
> diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
> index 5b212f0..c3499dd 100644
> --- a/drivers/scsi/aic7xxx_old.c
> +++ b/drivers/scsi/aic7xxx_old.c
> @@ -8306,7 +8306,7 @@ aic7xxx_register(struct scsi_host_template
*template,
> struct aic7xxx_host *p,
> "aic7xxx", p));
> if (result < 0)
> {
> - result = (request_irq(p->irq, do_aic7xxx_isr, IRQF_DISABLED |
> IRQF_SHARED,
> + result = (request_irq(p->irq, do_aic7xxx_isr, IRQF_SHARED,
> "aic7xxx", p));
> }
> }
> diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
> index c454e44..d58ea8e 100644
> --- a/drivers/scsi/arm/acornscsi.c
> +++ b/drivers/scsi/arm/acornscsi.c
> @@ -2997,7 +2997,7 @@ acornscsi_probe(struct expansion_card *ec, const
struct
> ecard_id *id)
> ec->irqaddr = ashost->fast + INT_REG;
> ec->irqmask = 0x0a;
>
> - ret = request_irq(host->irq, acornscsi_intr, IRQF_DISABLED,
"acornscsi",
> ashost);
> + ret = request_irq(host->irq, acornscsi_intr, 0, "acornscsi",
ashost);
> if (ret) {
> printk(KERN_CRIT "scsi%d: IRQ%d not free: %d\n",
> host->host_no, ashost->scsi.irq, ret);
> diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
> index a3398fe..c5f46ba 100644
> --- a/drivers/scsi/arm/cumana_1.c
> +++ b/drivers/scsi/arm/cumana_1.c
> @@ -264,7 +264,7 @@ cumanascsi1_probe(struct expansion_card *ec, const
struct
> ecard_id *id)
> goto out_unmap;
> }
>
> - ret = request_irq(host->irq, cumanascsi_intr, IRQF_DISABLED,
> + ret = request_irq(host->irq, cumanascsi_intr, 0,
> "CumanaSCSI-1", host);
> if (ret) {
> printk("scsi%d: IRQ%d not free: %d\n",
> diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c
> index 547987b..084ed7b 100644
> --- a/drivers/scsi/arm/cumana_2.c
> +++ b/drivers/scsi/arm/cumana_2.c
> @@ -456,7 +456,7 @@ cumanascsi2_probe(struct expansion_card *ec, const
struct
> ecard_id *id)
> goto out_free;
>
> ret = request_irq(ec->irq, cumanascsi_2_intr,
> - IRQF_DISABLED, "cumanascsi2", info);
> + 0, "cumanascsi2", info);
> if (ret) {
> printk("scsi%d: IRQ%d not free: %d\n",
> host->host_no, ec->irq, ret);
> diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c
> index 9274c06..49ac0c2 100644
> --- a/drivers/scsi/arm/powertec.c
> +++ b/drivers/scsi/arm/powertec.c
> @@ -369,7 +369,7 @@ powertecscsi_probe(struct expansion_card *ec, const
struct
> ecard_id *id)
> goto out_free;
>
> ret = request_irq(ec->irq, powertecscsi_intr,
> - IRQF_DISABLED, "powertec", info);
> + 0, "powertec", info);
> if (ret) {
> printk("scsi%d: IRQ%d not free: %d\n",
> host->host_no, ec->irq, ret);
> diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c
> index c2677ba..c77c820 100644
> --- a/drivers/scsi/dtc.c
> +++ b/drivers/scsi/dtc.c
> @@ -277,7 +277,7 @@ found:
> /* With interrupts enabled, it will sometimes hang when
doing heavy
> * reads. So better not enable them until I finger it out.
*/
> if (instance->irq != SCSI_IRQ_NONE)
> - if (request_irq(instance->irq, dtc_intr,
IRQF_DISABLED,
> + if (request_irq(instance->irq, dtc_intr, 0,
> "dtc", instance)) {
> printk(KERN_ERR "scsi%d : IRQ%d not free,
interrupts
> disabled\n", instance->host_no, instance->irq);
> instance->irq = SCSI_IRQ_NONE;
> diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
> index 94de889..bc2e02e 100644
> --- a/drivers/scsi/eata.c
> +++ b/drivers/scsi/eata.c
> @@ -1221,7 +1221,7 @@ static int port_detect(unsigned long port_base,
unsigned
> int j,
>
> /* Board detected, allocate its IRQ */
> if (request_irq(irq, do_interrupt_handler,
> - IRQF_DISABLED | ((subversion == ESA) ? IRQF_SHARED :
0),
> + ((subversion == ESA) ? IRQF_SHARED : 0),
> driver_name, (void *)&sha[j])) {
> printk("%s: unable to allocate IRQ %u, detaching.\n", name,
> irq);
> diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c
> index d5f8362..dcc9820 100644
> --- a/drivers/scsi/eata_pio.c
> +++ b/drivers/scsi/eata_pio.c
> @@ -723,7 +723,7 @@ static int register_pio_HBA(long base, struct get_conf
*gc,
> struct pci_dev *pdev
> return 0;
>
> if (!reg_IRQ[gc->IRQ]) { /* Interrupt already registered ? */
> - if (!request_irq(gc->IRQ, do_eata_pio_int_handler,
IRQF_DISABLED,
> "EATA-PIO", sh)) {
> + if (!request_irq(gc->IRQ, do_eata_pio_int_handler, 0,
"EATA-PIO",
> sh)) {
> reg_IRQ[gc->IRQ]++;
> if (!gc->IRQ_TR)
> reg_IRQL[gc->IRQ] = 1; /* IRQ is edge
triggered */
> @@ -957,7 +957,7 @@ static int eata_pio_detect(struct scsi_host_template
> *tpnt)
>
> for (i = 0; i <= MAXIRQ; i++)
> if (reg_IRQ[i])
> - request_irq(i, do_eata_pio_int_handler,
IRQF_DISABLED,
> "EATA-PIO", NULL);
> + request_irq(i, do_eata_pio_int_handler, 0,
"EATA-PIO", NULL);
>
> HBA_ptr = first_HBA;
>
> diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
> index 81182ba..72cf40f 100644
> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -462,7 +462,7 @@ int __init generic_NCR5380_detect(struct
> scsi_host_template * tpnt)
>
> if (instance->irq != SCSI_IRQ_NONE)
> if (request_irq(instance->irq, generic_NCR5380_intr,
> - IRQF_DISABLED, "NCR5380", instance))
{
> + 0, "NCR5380", instance)) {
> printk(KERN_WARNING "scsi%d : IRQ%d not
free, interrupts
> disabled\n", instance->host_no, instance->irq);
> instance->irq = SCSI_IRQ_NONE;
> }
> diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
> index 3242bca..045cc61 100644
> --- a/drivers/scsi/gdth.c
> +++ b/drivers/scsi/gdth.c
> @@ -4718,7 +4718,7 @@ static int __init gdth_isa_probe_one(u32 isa_bios)
> printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n",
> isa_bios, ha->irq, ha->drq);
>
> - error = request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED, "gdth",
ha);
> + error = request_irq(ha->irq, gdth_interrupt, 0, "gdth", ha);
> if (error) {
> printk("GDT-ISA: Unable to allocate IRQ\n");
> goto out_host_put;
> @@ -4850,7 +4850,7 @@ static int __init gdth_eisa_probe_one(u16 eisa_slot)
> printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n",
> eisa_slot >> 12, ha->irq);
>
> - error = request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED, "gdth",
ha);
> + error = request_irq(ha->irq, gdth_interrupt, 0, "gdth", ha);
> if (error) {
> printk("GDT-EISA: Unable to allocate IRQ\n");
> goto out_host_put;
> @@ -4987,7 +4987,7 @@ static int __devinit gdth_pci_probe_one(gdth_pci_str
> *pcistr,
> ha->irq);
>
> error = request_irq(ha->irq, gdth_interrupt,
> - IRQF_DISABLED|IRQF_SHARED, "gdth", ha);
> + IRQF_SHARED, "gdth", ha);
> if (error) {
> printk("GDT-PCI: Unable to allocate IRQ\n");
> goto out_host_put;
> diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
> index b200b73..444ea3b 100644
> --- a/drivers/scsi/hpsa.c
> +++ b/drivers/scsi/hpsa.c
> @@ -4025,10 +4025,10 @@ static int hpsa_request_irq(struct ctlr_info *h,
>
> if (h->msix_vector || h->msi_vector)
> rc = request_irq(h->intr[h->intr_mode], msixhandler,
> - IRQF_DISABLED, h->devname, h);
> + 0, h->devname, h);
> else
> rc = request_irq(h->intr[h->intr_mode], intxhandler,
> - IRQF_DISABLED, h->devname, h);
> + 0, h->devname, h);
> if (rc) {
> dev_err(&h->pdev->dev, "unable to get irq %d for %s\n",
> h->intr[h->intr_mode], h->devname);
> diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c
> b/drivers/scsi/ibmvscsi/ibmvstgt.c
> index 2256bab..41d42f2 100644
> --- a/drivers/scsi/ibmvscsi/ibmvstgt.c
> +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c
> @@ -589,7 +589,7 @@ static int crq_queue_create(struct crq_queue *queue,
> struct srp_target *target)
> }
>
> err = request_irq(vport->dma_dev->irq, &ibmvstgt_interrupt,
> - IRQF_DISABLED, "ibmvstgt", target);
> + 0, "ibmvstgt", target);
> if (err)
> goto req_irq_failed;
>
> diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
> index 112f1be..1efb20b 100644
> --- a/drivers/scsi/in2000.c
> +++ b/drivers/scsi/in2000.c
> @@ -2016,7 +2016,7 @@ static int __init in2000_detect(struct
> scsi_host_template * tpnt)
> write1_io(0, IO_FIFO_READ); /* start fifo out in read
mode */
> write1_io(0, IO_INTR_MASK); /* allow all ints */
> x = int_tab[(switches & (SW_INT0 | SW_INT1)) >>
SW_INT_SHIFT];
> - if (request_irq(x, in2000_intr, IRQF_DISABLED, "in2000",
instance))
> {
> + if (request_irq(x, in2000_intr, 0, "in2000", instance)) {
> printk("in2000_detect: Unable to allocate IRQ.\n");
> detect_count--;
> continue;
> diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c
> index dd741bc..4c80c7d 100644
> --- a/drivers/scsi/initio.c
> +++ b/drivers/scsi/initio.c
> @@ -2931,7 +2931,7 @@ static int initio_probe_one(struct pci_dev *pdev,
> shost->base = host->addr;
> shost->sg_tablesize = TOTAL_SG_ENTRY;
>
> - error = request_irq(pdev->irq, i91u_intr, IRQF_DISABLED|IRQF_SHARED,
> "i91u", shost);
> + error = request_irq(pdev->irq, i91u_intr, IRQF_SHARED, "i91u",
shost);
> if (error < 0) {
> printk(KERN_WARNING "initio: Unable to request IRQ %d\n",
> pdev->irq);
> goto out_free_scbs;
> diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c
> index f2018b4..e75d43d 100644
> --- a/drivers/scsi/pas16.c
> +++ b/drivers/scsi/pas16.c
> @@ -453,7 +453,7 @@ int __init pas16_detect(struct scsi_host_template *
tpnt)
> instance->irq = NCR5380_probe_irq(instance, PAS16_IRQS);
>
> if (instance->irq != SCSI_IRQ_NONE)
> - if (request_irq(instance->irq, pas16_intr, IRQF_DISABLED,
> + if (request_irq(instance->irq, pas16_intr, 0,
> "pas16", instance)) {
> printk("scsi%d : IRQ%d not free, interrupts disabled\n",
> instance->host_no, instance->irq);
> diff --git a/drivers/scsi/pm8001/pm8001_init.c
> b/drivers/scsi/pm8001/pm8001_init.c
> index 172cefb..d148ba3 100644
> --- a/drivers/scsi/pm8001/pm8001_init.c
> +++ b/drivers/scsi/pm8001/pm8001_init.c
> @@ -553,12 +553,10 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info
> *pm8001_ha,
> {
> u32 i = 0, j = 0;
> u32 number_of_intr = 1;
> - int flag = 0;
> u32 max_entry;
> int rc;
> max_entry = sizeof(pm8001_ha->msix_entries) /
> sizeof(pm8001_ha->msix_entries[0]);
> - flag |= IRQF_DISABLED;
> for (i = 0; i < max_entry ; i++)
> pm8001_ha->msix_entries[i].entry = i;
> rc = pci_enable_msix(pm8001_ha->pdev, pm8001_ha->msix_entries,
> @@ -567,7 +565,7 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info
> *pm8001_ha,
> if (!rc) {
> for (i = 0; i < number_of_intr; i++) {
> if (request_irq(pm8001_ha->msix_entries[i].vector,
> - irq_handler, flag, DRV_NAME,
> + irq_handler, 0, DRV_NAME,
> SHOST_TO_SAS_HA(pm8001_ha->shost))) {
> for (j = 0; j < i; j++)
> free_irq(
> diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c
> index 041eaaa..d9142a2 100644
> --- a/drivers/scsi/t128.c
> +++ b/drivers/scsi/t128.c
> @@ -259,7 +259,7 @@ found:
> instance->irq = NCR5380_probe_irq(instance, T128_IRQS);
>
> if (instance->irq != SCSI_IRQ_NONE)
> - if (request_irq(instance->irq, t128_intr, IRQF_DISABLED, "t128",
> + if (request_irq(instance->irq, t128_intr, 0, "t128",
> instance)) {
> printk("scsi%d : IRQ%d not free, interrupts disabled\n",
> instance->host_no, instance->irq);
> diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
> index 90e104d..5c50f9c 100644
> --- a/drivers/scsi/u14-34f.c
> +++ b/drivers/scsi/u14-34f.c
> @@ -874,7 +874,7 @@ static int port_detect \
>
> /* Board detected, allocate its IRQ */
> if (request_irq(irq, do_interrupt_handler,
> - IRQF_DISABLED | ((subversion == ESA) ? IRQF_SHARED : 0),
> + ((subversion == ESA) ? IRQF_SHARED : 0),
> driver_name, (void *) &sha[j])) {
> printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
> goto freelock;
> diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
> index 9ee0afe..8cab246 100644
> --- a/drivers/scsi/wd7000.c
> +++ b/drivers/scsi/wd7000.c
> @@ -1253,7 +1253,7 @@ static int wd7000_init(Adapter * host)
> return 0;
>
>
> - if (request_irq(host->irq, wd7000_intr, IRQF_DISABLED, "wd7000",
host))
> {
> + if (request_irq(host->irq, wd7000_intr, 0, "wd7000", host)) {
> printk("wd7000_init: can't get IRQ %d.\n", host->irq);
> return (0);
> }
> --
> 1.7.4.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2] dmaengine: add CSR SiRFprimaII DMAC driver
From: Barry Song @ 2011-09-23 2:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201109211649.01440.arnd@arndb.de>
Hi Arnd,
Thanks for review and good comments.
2011/9/21 Arnd Bergmann <arnd@arndb.de>:
> Hi Barry,
>
> I just looked at the driver again and stumbled over a potential race:
>
> On Friday 16 September 2011, Barry Song wrote:
>> +
>> +/* Execute all queued DMA descriptors */
>> +static void sirfsoc_dma_execute(struct sirfsoc_dma_chan *schan)
>> +{
>> + ? ? ? struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(&schan->chan);
>> + ? ? ? int cid = schan->chan.chan_id;
>> + ? ? ? struct sirfsoc_dma_desc *sdesc = NULL;
>> +
>> + ? ? ? sdesc = list_first_entry(&schan->queued, struct sirfsoc_dma_desc,
>> + ? ? ? ? ? ? ? node);
>> + ? ? ? /* Move the first queued descriptor to active list */
>> + ? ? ? list_move_tail(&schan->queued, &schan->active);
>> +
>> + ? ? ? /* Start the DMA transfer */
>> + ? ? ? writel_relaxed(sdesc->width, sdma->base + SIRFSOC_DMA_WIDTH_0 + cid * 4);
>> + ? ? ? writel_relaxed(cid | (schan->mode << SIRFSOC_DMA_MODE_CTRL_BIT) |
>> + ? ? ? ? ? ? ? (schan->direction << SIRFSOC_DMA_DIR_CTRL_BIT),
>> + ? ? ? ? ? ? ? sdma->base + cid * 0x10 + SIRFSOC_DMA_CH_CTRL);
>> + ? ? ? writel_relaxed(sdesc->xlen, sdma->base + cid * 0x10 + SIRFSOC_DMA_CH_XLEN);
>> + ? ? ? writel_relaxed(sdesc->ylen, sdma->base + cid * 0x10 + SIRFSOC_DMA_CH_YLEN);
>> + ? ? ? writel_relaxed(readl_relaxed(sdma->base + SIRFSOC_DMA_INT_EN) | (1 << cid),
>> + ? ? ? ? ? ? ? sdma->base + SIRFSOC_DMA_INT_EN);
>> + ? ? ? writel_relaxed(schan->addr >> 2, sdma->base + cid * 0x10 + SIRFSOC_DMA_CH_ADDR);
>> +}
>
> I think you need to add a memory write barrier somewhere in here, because
> writel_relaxed() does not flush out the CPUs write buffers, unlike writel().
>
> Theoretically, you might be starting a DMA that reads from coherent memory
> but the data is still stuck in the CPU. I assume that the last writel_relaxed()
> is the access that actually starts the DMA, so it should be airtight once you
> replace that with writel().
yes. ARM_DMA_MEM_BUFFERABLE is forced on for CPU_V7 like primaII. we
used __raw_writel or writel_relaxed
before and haven't gotten any bug reported until now. anyway, actually
i need the IO barrier.
>
>> +/* Interrupt handler */
>> +static irqreturn_t sirfsoc_dma_irq(int irq, void *data)
>> +{
>> + ? ? ? struct sirfsoc_dma *sdma = data;
>> + ? ? ? struct sirfsoc_dma_chan *schan;
>> + ? ? ? u32 is;
>> + ? ? ? int ch;
>> +
>> + ? ? ? is = readl_relaxed(sdma->base + SIRFSOC_DMA_CH_INT);
>> + ? ? ? while ((ch = fls(is) - 1) >= 0) {
>> + ? ? ? ? ? ? ? is &= ~(1 << ch);
>> + ? ? ? ? ? ? ? writel_relaxed(1 << ch, sdma->base + SIRFSOC_DMA_CH_INT);
>> + ? ? ? ? ? ? ? schan = &sdma->channels[ch];
>> +
>> + ? ? ? ? ? ? ? spin_lock(&schan->lock);
>> +
>> + ? ? ? ? ? ? ? /* Execute queued descriptors */
>> + ? ? ? ? ? ? ? list_splice_tail_init(&schan->active, &schan->completed);
>> + ? ? ? ? ? ? ? if (!list_empty(&schan->queued))
>> + ? ? ? ? ? ? ? ? ? ? ? sirfsoc_dma_execute(schan);
>> +
>> + ? ? ? ? ? ? ? spin_unlock(&schan->lock);
>> + ? ? ? }
>
> Similarly, readl_relaxed() does might not force in inbound DMA to be
> completed, causing you to call the tasklet before the data is visible
> to the CPU. While your hardware might have better guarantees, the
> API you are using does not. It should be find when you replace the
> first read_relaxed with readl() here.
>
> ? ? ? ?Arnd
>
-barry
^ permalink raw reply
* [PATCH v3] of/irq: introduce of_irq_init
From: Rob Herring @ 2011-09-23 2:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316550244-3655-3-git-send-email-robherring2@gmail.com>
From: Rob Herring <rob.herring@calxeda.com>
of_irq_init will scan the devicetree for matching interrupt controller
nodes. Then it calls an initialization function for each found controller
in the proper order with parent nodes initialized before child nodes.
Based on initial pseudo code from Grant Likely.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
---
Changes from v2:
- add missing kfree's found by Jamie
- Implement Grant's comments to simplify the init loop
- fix function comments
drivers/of/irq.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/of_irq.h | 3 +
2 files changed, 109 insertions(+), 0 deletions(-)
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 6a5b5e7..aedd39b 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -19,10 +19,12 @@
*/
#include <linux/errno.h>
+#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/string.h>
+#include <linux/slab.h>
/* For archs that don't support NO_IRQ (such as x86), provide a dummy value */
#ifndef NO_IRQ
@@ -386,3 +388,107 @@ int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
return i;
}
+
+struct intc_desc {
+ struct list_head list;
+ struct device_node *dev;
+ struct device_node *interrupt_parent;
+};
+
+/**
+ * of_irq_init - Scan and init matching interrupt controllers in DT
+ * @matches: 0 terminated array of nodes to match and init function to call
+ *
+ * This function scans the device tree for matching interrupt controller nodes,
+ * and calls their initialization functions in order with parents first.
+ */
+void __init of_irq_init(const struct of_device_id *matches)
+{
+ struct device_node *np, *parent = NULL;
+ struct intc_desc *desc, *temp_desc;
+ struct list_head intc_desc_list, intc_parent_list;
+
+ INIT_LIST_HEAD(&intc_desc_list);
+ INIT_LIST_HEAD(&intc_parent_list);
+
+ for_each_matching_node(np, matches) {
+ if (!of_find_property(np, "interrupt-controller", NULL))
+ continue;
+ /* Here, we allocate and populate an intc_desc with the node
+ * pointer, interrupt-parent device_node etc. */
+ desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+ if (!desc) {
+ WARN_ON(1);
+ goto err;
+ }
+ desc->dev = np;
+ desc->interrupt_parent = of_irq_find_parent(np);
+ list_add_tail(&desc->list, &intc_desc_list);
+ }
+ if (list_empty(&intc_desc_list))
+ return;
+
+ /*
+ * The root irq controller is the one without an interrupt-parent.
+ * That one goes first, followed by the controllers that reference it,
+ * followed by the ones that reference the 2nd level controllers, etc
+ */
+ while (!list_empty(&intc_desc_list)) {
+ /*
+ * Process all controllers with the current 'parent'.
+ * First pass will be looking for NULL as the parent.
+ * The assumption is that NULL parent means a root controller.
+ */
+ list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
+ const struct of_device_id *match;
+ int ret;
+ of_irq_init_cb_t irq_init_cb;
+
+ if (desc->interrupt_parent != parent)
+ continue;
+
+ list_del(&desc->list);
+ match = of_match_node(matches, desc->dev);
+ if (!match || !match->data) {
+ kfree(desc);
+ continue;
+ }
+
+ pr_debug("of_irq_init: init %s @ %p, parent %p\n",
+ match->compatible,
+ desc->dev, desc->interrupt_parent);
+ irq_init_cb = match->data;
+ ret = irq_init_cb(desc->dev, desc->interrupt_parent);
+ if (ret) {
+ kfree(desc);
+ continue;
+ }
+
+ /*
+ * This one is now set up; add it to the parent list so
+ * its children can get processed in a subsequent pass.
+ */
+ list_add_tail(&desc->list, &intc_parent_list);
+ }
+
+ /* Get the next pending parent that might have children */
+ desc = list_first_entry(&intc_parent_list, typeof(*desc), list);
+ if (list_empty(&intc_parent_list) || !desc) {
+ pr_debug("of_irq_init: children remain, but no parents\n");
+ break;
+ }
+ list_del(&desc->list);
+ parent = desc->dev;
+ kfree(desc);
+ }
+
+ list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) {
+ list_del(&desc->list);
+ kfree(desc);
+ }
+err:
+ list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
+ list_del(&desc->list);
+ kfree(desc);
+ }
+}
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index cd2e61c..d0307ee 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -33,6 +33,8 @@ struct of_irq {
u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
};
+typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *);
+
/*
* Workarounds only applied to 32bit powermac machines
*/
@@ -73,6 +75,7 @@ extern int of_irq_to_resource_table(struct device_node *dev,
struct resource *res, int nr_irqs);
extern struct device_node *of_irq_find_parent(struct device_node *child);
+extern void of_irq_init(const struct of_device_id *matches);
#endif /* CONFIG_OF_IRQ */
#endif /* CONFIG_OF */
--
1.7.5.4
^ permalink raw reply related
* [PATCHv2 3/3] picoxcell: add the DTS for the PC7302 board
From: Barry Song @ 2011-09-23 2:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110915121512.GG3089@pulham.picochip.com>
2011/9/15 Jamie Iles <jamie@jamieiles.com>:
> On Thu, Sep 15, 2011 at 08:32:02AM -0300, Benjamin Herrenschmidt wrote:
>> On Wed, 2011-08-24 at 15:41 +0100, Jamie Iles wrote:
>>
>> > + ? chosen {
>> > + ? ? ? ? ? bootargs = "console=ttyS0,115200 earlyprintk loglevel=9 root=ubi0:rootfs rw rootfstype=ubifs ubi.mtd=5,2048";
>> > + ? ? ? ? ? linux,stdout-path = &uart0;
>> > + ? };
>>
>> Hrm... we don't normally put the bootargs in the device-tree.
>>
>> Either you have a way to pass it from a previous firmware (which
>> can then slap it into the device-tree at runtime), or you
>> can have a way to compile it in the kernel image but the device-tree
>> isn't the right place for it.
>
> OK, that's fair enough. ?A few other ARM platforms (tegra, prima2 and
> zynq) have bootargs in the chosen node and that's where I got it from,
> but our bootloader has fdt support so this can easily be removed.
some powerpc platforms also do that:
asp834x-redboot.dts: bootargs = "console=ttyS0,38400
root=/dev/mtdblock3 rootfstype=jffs2";
gamecube.dts: bootargs = "root=/dev/gcnsda2 rootwait udbg-immortal";
prpmc2800.dts: bootargs = "ip=on";
rainier.dts: bootargs = "console=ttyS0,115200";
sequoia.dts: bootargs = "console=ttyS0,115200";
virtex440-ml507.dts: bootargs = "console=ttyS0 root=/dev/ram";
virtex440-ml510.dts: bootargs = "console=ttyS0 root=/dev/ram";
wii.dts: bootargs = "root=/dev/mmcblk0p2 rootwait udbg-immortal";
if we have no bootargs in bootloader, kernel will use that one in DT.
>
> Thanks,
>
> Jamie
-barry
^ permalink raw reply
* [PATCH 15/19] plat-pxa: break out GPIO driver specifics
From: Haojian Zhuang @ 2011-09-23 2:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMPhdO-3AY-S6dsW4FU2qB5G_7ffqcpj7x3hD-T=uhBvSAzKBQ@mail.gmail.com>
>-----Original Message-----
>From: Eric Miao [mailto:eric.y.miao at gmail.com]
>Sent: 2011?9?21? 10:05 PM
>To: Linus Walleij; Haojian Zhuang
>Cc: Linus Walleij; Grant Likely; linux-kernel at vger.kernel.org; linux-
>arm-kernel at lists.infradead.org; Lee Jones; Russell King
>Subject: Re: [PATCH 15/19] plat-pxa: break out GPIO driver specifics
>
>On Tue, Sep 20, 2011 at 4:45 PM, Linus Walleij <linus.walleij@linaro.org>
>wrote:
>> On Wed, Aug 10, 2011 at 4:38 PM, Eric Miao <eric.y.miao@gmail.com>
>wrote:
>>> On Wed, Aug 10, 2011 at 8:18 PM, Linus Walleij
>>> <linus.walleij@stericsson.com> wrote:
>>>> From: Linus Walleij <linus.walleij@linaro.org>
>>>>
>>>> The <mach/gpio.h> file is included from upper directories
>>>> and deal with generic GPIO and gpiolib stuff. Break out the
>>>> platform and driver specific defines and functions into its own
>>>> header file.
>>>>
>>>> Cc: Eric Miao <eric.y.miao@gmail.com>
>>>> Cc: Russell King <linux@arm.linux.org.uk>
>>>> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
>>>
>>> I think there is better way around this, am working on it with
>several
>>> patches already, will release soon.
>>
>> Anything happening on this front or shall I update this patch set?
>
>Hi Linus,
>
>Several cleanup patches in my local tree but I didn't manage to find
>time to finish the series. Please go ahead update the patch set. We
>can fix the problems later.
>
>Haojian,
>
>Could you help on generalize the GPIO support code for PXA? Generally,
>the goals are:
>
>1. independent of <mach/gpio.h>, i.e. no #include <mach/gpio.h> so
>to support multiple sub-arch in a single kernel, that's to say -
>possible
>to build a single kernel supporting both mach-pxa/ and mach-mmp/
>
>2. as a result of 1), independent of <plat/gpio.h>
>
OK. I'll follow this.
>Thanks
>- eric
>
>>
>> Yours,
>> Linus Walleij
>>
^ permalink raw reply
* [PATCHv2 3/3] picoxcell: add the DTS for the PC7302 board
From: Benjamin Herrenschmidt @ 2011-09-23 2:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGsJ_4wniCS+85Hs7-vbaUyEL-yKEBnbgDOFPm0+THh6PMfCdw@mail.gmail.com>
On Fri, 2011-09-23 at 10:31 +0800, Barry Song wrote:
> 2011/9/15 Jamie Iles <jamie@jamieiles.com>:
> > On Thu, Sep 15, 2011 at 08:32:02AM -0300, Benjamin Herrenschmidt wrote:
> >> On Wed, 2011-08-24 at 15:41 +0100, Jamie Iles wrote:
> >>
> >> > + chosen {
> >> > + bootargs = "console=ttyS0,115200 earlyprintk loglevel=9 root=ubi0:rootfs rw rootfstype=ubifs ubi.mtd=5,2048";
> >> > + linux,stdout-path = &uart0;
> >> > + };
> >>
> >> Hrm... we don't normally put the bootargs in the device-tree.
> >>
> >> Either you have a way to pass it from a previous firmware (which
> >> can then slap it into the device-tree at runtime), or you
> >> can have a way to compile it in the kernel image but the device-tree
> >> isn't the right place for it.
> >
> > OK, that's fair enough. A few other ARM platforms (tegra, prima2 and
> > zynq) have bootargs in the chosen node and that's where I got it from,
> > but our bootloader has fdt support so this can easily be removed.
>
> some powerpc platforms also do that:
Right, I never said I was perfect :-)
> asp834x-redboot.dts: bootargs = "console=ttyS0,38400
> root=/dev/mtdblock3 rootfstype=jffs2";
> gamecube.dts: bootargs = "root=/dev/gcnsda2 rootwait udbg-immortal";
> prpmc2800.dts: bootargs = "ip=on";
> rainier.dts: bootargs = "console=ttyS0,115200";
> sequoia.dts: bootargs = "console=ttyS0,115200";
> virtex440-ml507.dts: bootargs = "console=ttyS0 root=/dev/ram";
> virtex440-ml510.dts: bootargs = "console=ttyS0 root=/dev/ram";
> wii.dts: bootargs = "root=/dev/mmcblk0p2 rootwait udbg-immortal";
>
> if we have no bootargs in bootloader, kernel will use that one in DT.
Cheers,
Ben.
^ permalink raw reply
* [PATCH v7 00/26] gpio/omap: driver cleanup and fixes
From: DebBarma, Tarun Kanti @ 2011-09-23 4:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87fwjotity.fsf@ti.com>
[...]
>>> This series is continuation of cleanup of OMAP GPIO driver and fixes.
>>> The cleanup include getting rid of cpu_is_* checks wherever possible,
>>> use of gpio_bank list instead of static array, use of unique platform
>>> specific value associated data member to OMAP platforms to avoid
>>> cpu_is_* checks. The series also include PM runtime support.*
>>>
>>> Baseline: git://gitorious.org/khilman/linux-omap-pm.git
>>> Branch: for_3.2/gpio-cleanup
>>> Commit: 8323374
>> Thanks Tony for ack'ing the patches.
>> Kevin,
>> Since Tony's has acked the patches, can you please pull them?
>
> Before merging, I still need to review and test this version, and I
> *might* still get to it this week.
That's fine. Thanks.
>
> Based on the dbclk aliases you added, I assume this has now been tested
> on platforms using some GPIOs with debounce enabled?
I have replicated gpio_debounce() code within *_gpio_mod_init() whereby
_set_gpio_debounce() is called to enable debounce.
After this, confirmed system going to off-mode through the CPU IDLE path.
--
Tarun
>
> Kevin
>
^ permalink raw reply
* [RFC PATCH v3] drivercore: Add driver probe deferral mechanism
From: Grant Likely @ 2011-09-23 5:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110922234737.05dff9f8@lxorguk.ukuu.org.uk>
On Thu, Sep 22, 2011 at 11:47:37PM +0100, Alan Cox wrote:
> > How would a given driver know that something else is waiting for it? Or
> > would we add the explicit kick to each and every driver in the tree?
>
> I think there are very very few drivers that have this property and don't
> already implicitly cause a probe by creating a new bus or device.
>
> Those drivers that set something up for another device really should
> know what is going on because they are making a guarantee that they are
> ready for the other device to call into them or whatever is going on at
> some point, either explicitly in the kick or implicitly in returning from
> their probe method.
I disagree. There are lots of situations we're hitting where the
providing driver and the consuming driver don't have any details about
each other except for the name/reference of the resource (be it gpio,
phy, clock, regulator; each with a different API).
Example 1: ALSA SoC complex. A codec sitting on an i2c bus that gets
bound to an i2c_driver and attached to a memory-mapped I2S controller
driven by a platform_driver. The sound device cannot be created until
both the i2c codec and the i2s controller are bound to their drivers.
Example 2: an SDHCI controller which uses a couple of GPIO lines for
card detect and write protect, but the board designer may choose to
use any available gpio line, such as on an spi gpio expander.
Example 3: An Ethernet controller attached to a phy on a completely
independent MDIO bus. The Ethernet driver uses the phylib api to
access the phy, but cannot do so until after the phy device is bound
to a driver.
These are three very quickly off the top of my head. I can easily
come up with a lot more.
The whole point is that the consumers *don't* and *should not* know anything
how its required resources are provided. The consumer only knows how
to request them. Similarly, providers don't know anything about which
devices are going to be requesting resources from them. They can only
publish what they provide.
Now, if I'm understanding what you're suggesting, we could cause the
re-probe to be triggered only when new gpio banks, phys, clocks,
regulators, audio codecs, audio busses, interrupt controllers, and dma
engines are registered. This means adding the trigger call to all the
registration paths we think are relevant. Personally, I really don't
think this is going to be worth it given the projected order of
complexity. It is because the dependencies could be any interface
provided by another driver, I don't want to start with limitations on
exactly which interfaces can use probe deferral.
g.
^ permalink raw reply
* [PATCH v3] of/irq: introduce of_irq_init
From: Grant Likely @ 2011-09-23 5:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316744473-13158-1-git-send-email-robherring2@gmail.com>
On Thu, Sep 22, 2011 at 09:21:13PM -0500, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> of_irq_init will scan the devicetree for matching interrupt controller
> nodes. Then it calls an initialization function for each found controller
> in the proper order with parent nodes initialized before child nodes.
>
> Based on initial pseudo code from Grant Likely.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
Looking really good, comments below...
> ---
> Changes from v2:
> - add missing kfree's found by Jamie
> - Implement Grant's comments to simplify the init loop
> - fix function comments
Nit: put changelog above the s-o-b lines so that it appears in the git
commit text.
>
> drivers/of/irq.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/of_irq.h | 3 +
> 2 files changed, 109 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/of/irq.c b/drivers/of/irq.c
> index 6a5b5e7..aedd39b 100644
> --- a/drivers/of/irq.c
> +++ b/drivers/of/irq.c
> @@ -19,10 +19,12 @@
> */
>
> #include <linux/errno.h>
> +#include <linux/list.h>
> #include <linux/module.h>
> #include <linux/of.h>
> #include <linux/of_irq.h>
> #include <linux/string.h>
> +#include <linux/slab.h>
>
> /* For archs that don't support NO_IRQ (such as x86), provide a dummy value */
> #ifndef NO_IRQ
> @@ -386,3 +388,107 @@ int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
>
> return i;
> }
> +
> +struct intc_desc {
> + struct list_head list;
> + struct device_node *dev;
> + struct device_node *interrupt_parent;
> +};
> +
> +/**
> + * of_irq_init - Scan and init matching interrupt controllers in DT
> + * @matches: 0 terminated array of nodes to match and init function to call
> + *
> + * This function scans the device tree for matching interrupt controller nodes,
> + * and calls their initialization functions in order with parents first.
> + */
> +void __init of_irq_init(const struct of_device_id *matches)
> +{
> + struct device_node *np, *parent = NULL;
> + struct intc_desc *desc, *temp_desc;
> + struct list_head intc_desc_list, intc_parent_list;
> +
> + INIT_LIST_HEAD(&intc_desc_list);
> + INIT_LIST_HEAD(&intc_parent_list);
> +
> + for_each_matching_node(np, matches) {
> + if (!of_find_property(np, "interrupt-controller", NULL))
> + continue;
> + /* Here, we allocate and populate an intc_desc with the node
> + * pointer, interrupt-parent device_node etc. */
nit: weird indenting
> + desc = kzalloc(sizeof(*desc), GFP_KERNEL);
> + if (!desc) {
> + WARN_ON(1);
> + goto err;
> + }
> + desc->dev = np;
> + desc->interrupt_parent = of_irq_find_parent(np);
> + list_add_tail(&desc->list, &intc_desc_list);
> + }
> + if (list_empty(&intc_desc_list))
> + return;
This test in unnecessary
> +
> + /*
> + * The root irq controller is the one without an interrupt-parent.
> + * That one goes first, followed by the controllers that reference it,
> + * followed by the ones that reference the 2nd level controllers, etc
> + */
> + while (!list_empty(&intc_desc_list)) {
> + /*
> + * Process all controllers with the current 'parent'.
> + * First pass will be looking for NULL as the parent.
> + * The assumption is that NULL parent means a root controller.
> + */
> + list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
> + const struct of_device_id *match;
> + int ret;
> + of_irq_init_cb_t irq_init_cb;
> +
> + if (desc->interrupt_parent != parent)
> + continue;
> +
> + list_del(&desc->list);
> + match = of_match_node(matches, desc->dev);
> + if (!match || !match->data) {
match will always be !NULL. If match_data is NULL; something is
seriously wrong and the code should WARN().
> + kfree(desc);
> + continue;
> + }
> +
> + pr_debug("of_irq_init: init %s @ %p, parent %p\n",
> + match->compatible,
> + desc->dev, desc->interrupt_parent);
> + irq_init_cb = match->data;
> + ret = irq_init_cb(desc->dev, desc->interrupt_parent);
> + if (ret) {
> + kfree(desc);
> + continue;
> + }
> +
> + /*
> + * This one is now set up; add it to the parent list so
> + * its children can get processed in a subsequent pass.
> + */
> + list_add_tail(&desc->list, &intc_parent_list);
> + }
> +
> + /* Get the next pending parent that might have children */
> + desc = list_first_entry(&intc_parent_list, typeof(*desc), list);
> + if (list_empty(&intc_parent_list) || !desc) {
> + pr_debug("of_irq_init: children remain, but no parents\n");
This is an error condition. Use pr_err()
> + break;
> + }
> + list_del(&desc->list);
> + parent = desc->dev;
> + kfree(desc);
> + }
> +
> + list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) {
> + list_del(&desc->list);
> + kfree(desc);
> + }
> +err:
> + list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
> + list_del(&desc->list);
> + kfree(desc);
> + }
> +}
> diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
> index cd2e61c..d0307ee 100644
> --- a/include/linux/of_irq.h
> +++ b/include/linux/of_irq.h
> @@ -33,6 +33,8 @@ struct of_irq {
> u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
> };
>
> +typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *);
> +
> /*
> * Workarounds only applied to 32bit powermac machines
> */
> @@ -73,6 +75,7 @@ extern int of_irq_to_resource_table(struct device_node *dev,
> struct resource *res, int nr_irqs);
> extern struct device_node *of_irq_find_parent(struct device_node *child);
>
> +extern void of_irq_init(const struct of_device_id *matches);
>
> #endif /* CONFIG_OF_IRQ */
> #endif /* CONFIG_OF */
> --
> 1.7.5.4
>
^ permalink raw reply
* [PATCH 0/4] ARM: CSR: cleanup some minor coding-style issues
From: Barry Song @ 2011-09-23 5:51 UTC (permalink / raw)
To: linux-arm-kernel
Barry Song (4):
ARM: CSR: timer: do not initialise statics to 0 or NULL
ARM: CSR: timer: space required before the open parenthesis '('
ARM: CSR: prima2: fix trailing whitespace
ARM: CSR: clock: Fix indentation
arch/arm/mach-prima2/clock.c | 4 ++--
arch/arm/mach-prima2/prima2.c | 2 +-
arch/arm/mach-prima2/timer.c | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog
^ permalink raw reply
* [PATCH 1/4] ARM: CSR: timer: do not initialise statics to 0 or NULL
From: Barry Song @ 2011-09-23 5:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316757091-14916-1-git-send-email-Baohua.Song@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
arch/arm/mach-prima2/timer.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c
index ed7ec48..225ed3b 100644
--- a/arch/arm/mach-prima2/timer.c
+++ b/arch/arm/mach-prima2/timer.c
@@ -133,7 +133,7 @@ static struct irqaction sirfsoc_timer_irq = {
/* Overwrite weak default sched_clock with more precise one */
unsigned long long notrace sched_clock(void)
{
- static int is_mapped = 0;
+ static int is_mapped;
/*
* sched_clock is called earlier than .init of sys_timer
--
1.7.1
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog
^ permalink raw reply related
* [PATCH 2/4] ARM: CSR: timer: space required before the open parenthesis '('
From: Barry Song @ 2011-09-23 5:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316757091-14916-1-git-send-email-Baohua.Song@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
arch/arm/mach-prima2/timer.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c
index 225ed3b..26ab6fe 100644
--- a/arch/arm/mach-prima2/timer.c
+++ b/arch/arm/mach-prima2/timer.c
@@ -140,7 +140,7 @@ unsigned long long notrace sched_clock(void)
* if we map timer memory in .init of sys_timer, system
* will panic due to illegal memory access
*/
- if(!is_mapped) {
+ if (!is_mapped) {
sirfsoc_of_timer_map();
is_mapped = 1;
}
--
1.7.1
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog
^ permalink raw reply related
* [PATCH 3/4] ARM: CSR: prima2: fix trailing whitespace
From: Barry Song @ 2011-09-23 5:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316757091-14916-1-git-send-email-Baohua.Song@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
arch/arm/mach-prima2/prima2.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-prima2/prima2.c b/arch/arm/mach-prima2/prima2.c
index f57124b..0ddf446 100644
--- a/arch/arm/mach-prima2/prima2.c
+++ b/arch/arm/mach-prima2/prima2.c
@@ -1,5 +1,5 @@
/*
- * Defines machines for CSR SiRFprimaII
+ * Defines machines for CSR SiRFprimaII
*
* Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
*
--
1.7.1
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog
^ permalink raw reply related
* [PATCH 4/4] ARM: CSR: clock: Fix indentation
From: Barry Song @ 2011-09-23 5:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316757091-14916-1-git-send-email-Baohua.Song@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
arch/arm/mach-prima2/clock.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-prima2/clock.c b/arch/arm/mach-prima2/clock.c
index 615a4e7..aebad7e 100644
--- a/arch/arm/mach-prima2/clock.c
+++ b/arch/arm/mach-prima2/clock.c
@@ -350,10 +350,10 @@ static struct clk_lookup onchip_clks[] = {
.clk = &clk_mem,
}, {
.dev_id = "sys",
- .clk = &clk_sys,
+ .clk = &clk_sys,
}, {
.dev_id = "io",
- .clk = &clk_io,
+ .clk = &clk_io,
},
};
--
1.7.1
Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog
^ permalink raw reply related
* [V3 4/4] ARM: mmp: support emmc on dkb board
From: Haojian Zhuang @ 2011-09-23 5:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316610446-24183-5-git-send-email-njun@marvell.com>
On Wed, Sep 21, 2011 at 9:07 PM, Jun Nie <njun@marvell.com> wrote:
> Signed-off-by: Jun Nie <njun@marvell.com>
> ---
> ?arch/arm/mach-mmp/ttc_dkb.c | ? 30 ++++++++++++++++++++++++++++++
> ?1 files changed, 30 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
> index f90e5db..0c05ecd 100644
> --- a/arch/arm/mach-mmp/ttc_dkb.c
> +++ b/arch/arm/mach-mmp/ttc_dkb.c
> @@ -50,6 +50,18 @@ static unsigned long ttc_dkb_pin_config[] __initdata = {
> ? ? ? ?GPIO47_UART2_RXD,
> ? ? ? ?GPIO48_UART2_TXD,
>
> +#ifdef DKB_EMMC
> + ? ? ? MFP_CFG(DF_IO0, AF1),
> + ? ? ? MFP_CFG(DF_IO1, AF1),
> + ? ? ? MFP_CFG(DF_IO2, AF1),
> + ? ? ? MFP_CFG(DF_IO3, AF1),
> + ? ? ? MFP_CFG(DF_IO4, AF1),
> + ? ? ? MFP_CFG(DF_IO5, AF1),
> + ? ? ? MFP_CFG(DF_IO6, AF1),
> + ? ? ? MFP_CFG(DF_IO7, AF1),
> + ? ? ? MFP_CFG(DF_CLE_SM_OEn, AF1),
> + ? ? ? MFP_CFG(SM_SCLK, AF1),
> +#else
> ? ? ? ?/* DFI */
> ? ? ? ?DF_IO0_ND_IO0,
> ? ? ? ?DF_IO1_ND_IO1,
> @@ -73,6 +85,7 @@ static unsigned long ttc_dkb_pin_config[] __initdata = {
> ? ? ? ?DF_WEn_DF_WEn,
> ? ? ? ?DF_REn_DF_REn,
> ? ? ? ?DF_RDY0_DF_RDY0,
> +#endif /* DKB_EMMC */
If the pin configurations are conflict for different types of one
platform, it's better
to use Kconfig. Since you can avoid to change your sourcecode.
>
> ? ? ? ?/*sdh MMC0*/
> ? ? ? ?MMC1_DAT3_MMC1_DAT3,
> @@ -96,6 +109,7 @@ static unsigned long ttc_dkb_pin_config[] __initdata = {
> ? ? ? ?GPIO15_GPIO,
> ?};
>
> +#ifndef DKB_EMMC
> ?static struct mtd_partition ttc_dkb_onenand_partitions[] = {
> ? ? ? ?{
> ? ? ? ? ? ? ? ?.name ? ? ? ? ? = "bootloader",
> @@ -147,9 +161,12 @@ static struct platform_device ttc_dkb_device_onenand = {
> ? ? ? ? ? ? ? ?.platform_data ?= &ttc_dkb_onenand_info,
> ? ? ? ?},
> ?};
> +#endif /* DKB_EMMC */
>
> ?static struct platform_device *ttc_dkb_devices[] = {
> +#ifndef DKB_EMMC
> ? ? ? ?&ttc_dkb_device_onenand,
> +#endif
> ?};
>
> ?static struct pca953x_platform_data max7312_data[] = {
> @@ -203,6 +220,16 @@ static struct sdhci_pxa_platdata pxa910_sdh_platdata_mmc0 = {
> ? ? ? ?.clk_delay_cycles ? ? ? = 2,
> ?};
>
> +/* MMC2 controller for EMMC */
> +#ifdef DKB_EMMC
> +static struct sdhci_pxa_platdata pxa910_sdh_platdata_mmc2 = {
> + ? ? ? .flags ? ? ? ? ? ? ? ? ?= PXA_FLAG_CARD_PERMANENT
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | PXA_FLAG_SD_8_BIT_CAPABLE_SLOT,
> + ? ? ? .clk_delay_sel ? ? ? ? ?= 1,
> + ? ? ? .clk_delay_cycles ? ? ? = 2,
> +};
> +#endif
> +
> ?/* MMC1 controller for SDIO */
> ?static struct sdhci_pxa_platdata pxa910_sdh_platdata_mmc1 = {
> ? ? ? ?.flags ? ? ? ? ? ? ? ? ?= PXA_FLAG_CARD_PERMANENT,
> @@ -216,6 +243,9 @@ static void __init ttc_dkb_init(void)
> ? ? ? ?pxa910_add_uart(1);
> ? ? ? ?pxa910_add_sdhost0(&pxa910_sdh_platdata_mmc0);
> ? ? ? ?pxa910_add_sdhost1(&pxa910_sdh_platdata_mmc1);
> +#ifdef DKB_EMMC
> + ? ? ? pxa910_add_sdhost2(&pxa910_sdh_platdata_mmc2);
> +#endif
>
> ? ? ? ?/* off-chip devices */
> ? ? ? ?pxa910_add_twsi(0, NULL, ARRAY_AND_SIZE(ttc_dkb_i2c_info));
> --
> 1.7.0.4
>
>
^ permalink raw reply
* [RFC] Shrink sched_clock some more
From: Kyungmin Park @ 2011-09-23 6:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1109221414200.12663@xanadu.home>
On Fri, Sep 23, 2011 at 3:16 AM, Nicolas Pitre <nico@fluxnic.net> wrote:
> On Thu, 22 Sep 2011, Russell King - ARM Linux wrote:
>
>> ... by getting rid of the fixed-constant optimization, and moving the
>> update code into arch/arm/kernel/sched_clock.c.
>>
>> Platforms now only have to supply a function to read the sched_clock
>> register, and some basic information such as the number of significant
>> bits and the tick rate.
>>
>> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
>
> Nice. ?Too bad for the fixed-constant optimization, but it wasn't used
> enough to justify the bloat.
>
> Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
>
For s5p time,
Tested-by: Kyungmin Park <kyungmin.park@samsung.com>
>
>> ---
>> ?arch/arm/include/asm/sched_clock.h ? ?| ? 98 +--------------------------------
>> ?arch/arm/kernel/sched_clock.c ? ? ? ? | ? 91 ++++++++++++++++++++++++++++--
>> ?arch/arm/mach-ixp4xx/common.c ? ? ? ? | ? 15 +----
>> ?arch/arm/mach-mmp/time.c ? ? ? ? ? ? ?| ? 15 +----
>> ?arch/arm/mach-omap1/time.c ? ? ? ? ? ?| ? 27 +--------
>> ?arch/arm/mach-omap2/timer.c ? ? ? ? ? | ? 21 +------
>> ?arch/arm/mach-pxa/time.c ? ? ? ? ? ? ?| ? 23 +-------
>> ?arch/arm/mach-sa1100/time.c ? ? ? ? ? | ? 27 +--------
>> ?arch/arm/mach-tegra/timer.c ? ? ? ? ? | ? 23 +-------
>> ?arch/arm/mach-u300/timer.c ? ? ? ? ? ?| ? 22 +------
>> ?arch/arm/plat-iop/time.c ? ? ? ? ? ? ?| ? 15 +----
>> ?arch/arm/plat-mxc/time.c ? ? ? ? ? ? ?| ? 15 +----
>> ?arch/arm/plat-nomadik/timer.c ? ? ? ? | ? 25 +-------
>> ?arch/arm/plat-omap/counter_32k.c ? ? ?| ? 39 +------------
>> ?arch/arm/plat-orion/time.c ? ? ? ? ? ?| ? 16 +----
>> ?arch/arm/plat-s5p/s5p-time.c ? ? ? ? ?| ? 29 +---------
>> ?arch/arm/plat-versatile/sched-clock.c | ? 26 +--------
>> ?17 files changed, 131 insertions(+), 396 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h
>> index c8e6ddf..2026a0c 100644
>> --- a/arch/arm/include/asm/sched_clock.h
>> +++ b/arch/arm/include/asm/sched_clock.h
>> @@ -11,109 +11,13 @@
>> ?#include <linux/kernel.h>
>> ?#include <linux/types.h>
>>
>> -struct clock_data {
>> - ? ? u64 epoch_ns;
>> - ? ? u32 epoch_cyc;
>> - ? ? u32 epoch_cyc_copy;
>> - ? ? u32 mult;
>> - ? ? u32 shift;
>> -};
>> -
>> -#define DEFINE_CLOCK_DATA(name) ? ? ?struct clock_data name
>> -
>> -static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift)
>> -{
>> - ? ? return (cyc * mult) >> shift;
>> -}
>> -
>> -/*
>> - * Atomically update the sched_clock epoch. ?Your update callback will
>> - * be called from a timer before the counter wraps - read the current
>> - * counter value, and call this function to safely move the epochs
>> - * forward. ?Only use this from the update callback.
>> - */
>> -static inline void update_sched_clock(struct clock_data *cd, u32 cyc, u32 mask)
>> -{
>> - ? ? unsigned long flags;
>> - ? ? u64 ns = cd->epoch_ns +
>> - ? ? ? ? ? ? cyc_to_ns((cyc - cd->epoch_cyc) & mask, cd->mult, cd->shift);
>> -
>> - ? ? /*
>> - ? ? ?* Write epoch_cyc and epoch_ns in a way that the update is
>> - ? ? ?* detectable in cyc_to_fixed_sched_clock().
>> - ? ? ?*/
>> - ? ? raw_local_irq_save(flags);
>> - ? ? cd->epoch_cyc = cyc;
>> - ? ? smp_wmb();
>> - ? ? cd->epoch_ns = ns;
>> - ? ? smp_wmb();
>> - ? ? cd->epoch_cyc_copy = cyc;
>> - ? ? raw_local_irq_restore(flags);
>> -}
>> -
>> -/*
>> - * If your clock rate is known at compile time, using this will allow
>> - * you to optimize the mult/shift loads away. ?This is paired with
>> - * init_fixed_sched_clock() to ensure that your mult/shift are correct.
>> - */
>> -static inline unsigned long long cyc_to_fixed_sched_clock(struct clock_data *cd,
>> - ? ? u32 cyc, u32 mask, u32 mult, u32 shift)
>> -{
>> - ? ? u64 epoch_ns;
>> - ? ? u32 epoch_cyc;
>> -
>> - ? ? /*
>> - ? ? ?* Load the epoch_cyc and epoch_ns atomically. ?We do this by
>> - ? ? ?* ensuring that we always write epoch_cyc, epoch_ns and
>> - ? ? ?* epoch_cyc_copy in strict order, and read them in strict order.
>> - ? ? ?* If epoch_cyc and epoch_cyc_copy are not equal, then we're in
>> - ? ? ?* the middle of an update, and we should repeat the load.
>> - ? ? ?*/
>> - ? ? do {
>> - ? ? ? ? ? ? epoch_cyc = cd->epoch_cyc;
>> - ? ? ? ? ? ? smp_rmb();
>> - ? ? ? ? ? ? epoch_ns = cd->epoch_ns;
>> - ? ? ? ? ? ? smp_rmb();
>> - ? ? } while (epoch_cyc != cd->epoch_cyc_copy);
>> -
>> - ? ? return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask, mult, shift);
>> -}
>> -
>> -/*
>> - * Otherwise, you need to use this, which will obtain the mult/shift
>> - * from the clock_data structure. ?Use init_sched_clock() with this.
>> - */
>> -static inline unsigned long long cyc_to_sched_clock(struct clock_data *cd,
>> - ? ? u32 cyc, u32 mask)
>> -{
>> - ? ? return cyc_to_fixed_sched_clock(cd, cyc, mask, cd->mult, cd->shift);
>> -}
>> -
>> ?/*
>> ? * Initialize the clock data - calculate the appropriate multiplier
>> ? * and shift. ?Also setup a timer to ensure that the epoch is refreshed
>> ? * at the appropriate time interval, which will call your update
>> ? * handler.
>> ? */
>> -void init_sched_clock(struct clock_data *, void (*)(void),
>> - ? ? unsigned int, unsigned long);
>> -
>> -/*
>> - * Use this initialization function rather than init_sched_clock() if
>> - * you're using cyc_to_fixed_sched_clock, which will warn if your
>> - * constants are incorrect.
>> - */
>> -static inline void init_fixed_sched_clock(struct clock_data *cd,
>> - ? ? void (*update)(void), unsigned int bits, unsigned long rate,
>> - ? ? u32 mult, u32 shift)
>> -{
>> - ? ? init_sched_clock(cd, update, bits, rate);
>> - ? ? if (cd->mult != mult || cd->shift != shift) {
>> - ? ? ? ? ? ? pr_crit("sched_clock: wrong multiply/shift: %u>>%u vs calculated %u>>%u\n"
>> - ? ? ? ? ? ? ? ? ? ? "sched_clock: fix multiply/shift to avoid scheduler hiccups\n",
>> - ? ? ? ? ? ? ? ? ? ? mult, shift, cd->mult, cd->shift);
>> - ? ? }
>> -}
>> +void init_sched_clock(u32 (*)(void), unsigned int, unsigned long);
>>
>> ?extern void sched_clock_postinit(void);
>>
>> diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
>> index 9a46370..dfee812 100644
>> --- a/arch/arm/kernel/sched_clock.c
>> +++ b/arch/arm/kernel/sched_clock.c
>> @@ -14,28 +14,107 @@
>>
>> ?#include <asm/sched_clock.h>
>>
>> +struct clock_data {
>> + ? ? u64 epoch_ns;
>> + ? ? u32 epoch_cyc;
>> + ? ? u32 epoch_cyc_copy;
>> + ? ? u32 mult;
>> + ? ? u32 shift;
>> + ? ? u32 mask;
>> +};
>> +
>> ?static void sched_clock_poll(unsigned long wrap_ticks);
>> ?static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0);
>> -static void (*sched_clock_update_fn)(void);
>> +static u32 (*sched_clock_read_fn)(void);
>> +static struct clock_data sched_clock_data;
>> +
>> +static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift)
>> +{
>> + ? ? return (cyc * mult) >> shift;
>> +}
>> +
>> +/*
>> + * Atomically update the sched_clock epoch. ?Your update callback will
>> + * be called from a timer before the counter wraps - read the current
>> + * counter value, and call this function to safely move the epochs
>> + * forward. ?Only use this from the update callback.
>> + */
>> +static inline void update_sched_clock(struct clock_data *cd, u32 cyc, u32 mask)
>> +{
>> + ? ? unsigned long flags;
>> + ? ? u64 ns = cd->epoch_ns +
>> + ? ? ? ? ? ? cyc_to_ns((cyc - cd->epoch_cyc) & mask, cd->mult, cd->shift);
>> +
>> + ? ? /*
>> + ? ? ?* Write epoch_cyc and epoch_ns in a way that the update is
>> + ? ? ?* detectable in cyc_to_sched_clock().
>> + ? ? ?*/
>> + ? ? raw_local_irq_save(flags);
>> + ? ? cd->epoch_cyc = cyc;
>> + ? ? smp_wmb();
>> + ? ? cd->epoch_ns = ns;
>> + ? ? smp_wmb();
>> + ? ? cd->epoch_cyc_copy = cyc;
>> + ? ? raw_local_irq_restore(flags);
>> +}
>> +
>> +static inline unsigned long long cyc_to_sched_clock(struct clock_data *cd,
>> + ? ? u32 cyc, u32 mask)
>> +{
>> + ? ? u64 epoch_ns;
>> + ? ? u32 epoch_cyc;
>> +
>> + ? ? /*
>> + ? ? ?* Load the epoch_cyc and epoch_ns atomically. ?We do this by
>> + ? ? ?* ensuring that we always write epoch_cyc, epoch_ns and
>> + ? ? ?* epoch_cyc_copy in strict order, and read them in strict order.
>> + ? ? ?* If epoch_cyc and epoch_cyc_copy are not equal, then we're in
>> + ? ? ?* the middle of an update, and we should repeat the load.
>> + ? ? ?*/
>> + ? ? do {
>> + ? ? ? ? ? ? epoch_cyc = cd->epoch_cyc;
>> + ? ? ? ? ? ? smp_rmb();
>> + ? ? ? ? ? ? epoch_ns = cd->epoch_ns;
>> + ? ? ? ? ? ? smp_rmb();
>> + ? ? } while (epoch_cyc != cd->epoch_cyc_copy);
>> +
>> + ? ? return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask,
>> + ? ? ? ? ? ? ? ? ? ? cd->mult, cd->shift);
>> +}
>>
>> ?static void sched_clock_poll(unsigned long wrap_ticks)
>> ?{
>> + ? ? struct clock_data *cd = &sched_clock_data;
>> ? ? ? mod_timer(&sched_clock_timer, round_jiffies(jiffies + wrap_ticks));
>> - ? ? sched_clock_update_fn();
>> + ? ? update_sched_clock(cd, sched_clock_read_fn(), cd->mask);
>> ?}
>>
>> -void __init init_sched_clock(struct clock_data *cd, void (*update)(void),
>> +unsigned long long notrace sched_clock(void)
>> +{
>> + ? ? struct clock_data *cd = &sched_clock_data;
>> + ? ? u32 cyc = 0;
>> +
>> + ? ? if (sched_clock_read_fn)
>> + ? ? ? ? ? ? cyc = sched_clock_read_fn();
>> +
>> + ? ? return cyc_to_sched_clock(cd, cyc, cd->mask);
>> +}
>> +
>> +void __init init_sched_clock(u32 (*read)(void),
>> ? ? ? unsigned int clock_bits, unsigned long rate)
>> ?{
>> + ? ? struct clock_data *cd = &sched_clock_data;
>> ? ? ? unsigned long r, w;
>> ? ? ? u64 res, wrap;
>> ? ? ? char r_unit;
>>
>> - ? ? sched_clock_update_fn = update;
>> + ? ? sched_clock_read_fn = read;
>>
>> ? ? ? /* calculate the mult/shift to convert counter ticks to ns. */
>> ? ? ? clocks_calc_mult_shift(&cd->mult, &cd->shift, rate, NSEC_PER_SEC, 0);
>>
>> + ? ? cd->mask = (1ULL << clock_bits) - 1;
>> +
>> ? ? ? r = rate;
>> ? ? ? if (r >= 4000000) {
>> ? ? ? ? ? ? ? r /= 1000000;
>> @@ -46,7 +125,7 @@ void __init init_sched_clock(struct clock_data *cd, void (*update)(void),
>> ? ? ? }
>>
>> ? ? ? /* calculate how many ns until we wrap */
>> - ? ? wrap = cyc_to_ns((1ULL << clock_bits) - 1, cd->mult, cd->shift);
>> + ? ? wrap = cyc_to_ns(cd->mask, cd->mult, cd->shift);
>> ? ? ? do_div(wrap, NSEC_PER_MSEC);
>> ? ? ? w = wrap;
>>
>> @@ -60,7 +139,7 @@ void __init init_sched_clock(struct clock_data *cd, void (*update)(void),
>> ? ? ? ?* sets the initial epoch.
>> ? ? ? ?*/
>> ? ? ? sched_clock_timer.data = msecs_to_jiffies(w - (w / 10));
>> - ? ? update();
>> + ? ? update_sched_clock(cd, read(), cd->mask);
>>
>> ? ? ? /*
>> ? ? ? ?* Ensure that sched_clock() starts off at 0ns
>> diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
>> index 0777257..2951db0 100644
>> --- a/arch/arm/mach-ixp4xx/common.c
>> +++ b/arch/arm/mach-ixp4xx/common.c
>> @@ -402,18 +402,9 @@ void __init ixp4xx_sys_init(void)
>> ?/*
>> ? * sched_clock()
>> ? */
>> -static DEFINE_CLOCK_DATA(cd);
>> -
>> -unsigned long long notrace sched_clock(void)
>> +static u32 notrace ixp4xx_sched_clock_read(void)
>> ?{
>> - ? ? u32 cyc = *IXP4XX_OSTS;
>> - ? ? return cyc_to_sched_clock(&cd, cyc, (u32)~0);
>> -}
>> -
>> -static void notrace ixp4xx_update_sched_clock(void)
>> -{
>> - ? ? u32 cyc = *IXP4XX_OSTS;
>> - ? ? update_sched_clock(&cd, cyc, (u32)~0);
>> + ? ? return *IXP4XX_OSTS;
>> ?}
>>
>> ?/*
>> @@ -429,7 +420,7 @@ unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
>> ?EXPORT_SYMBOL(ixp4xx_timer_freq);
>> ?static void __init ixp4xx_clocksource_init(void)
>> ?{
>> - ? ? init_sched_clock(&cd, ixp4xx_update_sched_clock, 32, ixp4xx_timer_freq);
>> + ? ? init_sched_clock(ixp4xx_sched_clock_read, 32, ixp4xx_timer_freq);
>>
>> ? ? ? clocksource_mmio_init(NULL, "OSTS", ixp4xx_timer_freq, 200, 32,
>> ? ? ? ? ? ? ? ? ? ? ? ixp4xx_clocksource_read);
>> diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
>> index 4e91ee6..11f2bf1 100644
>> --- a/arch/arm/mach-mmp/time.c
>> +++ b/arch/arm/mach-mmp/time.c
>> @@ -42,8 +42,6 @@
>> ?#define MAX_DELTA ? ? ? ? ? ?(0xfffffffe)
>> ?#define MIN_DELTA ? ? ? ? ? ?(16)
>>
>> -static DEFINE_CLOCK_DATA(cd);
>> -
>> ?/*
>> ? * FIXME: the timer needs some delay to stablize the counter capture
>> ? */
>> @@ -59,16 +57,9 @@ static inline uint32_t timer_read(void)
>> ? ? ? return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(1));
>> ?}
>>
>> -unsigned long long notrace sched_clock(void)
>> +static u32 notrace mmp_sched_clock_read(void)
>> ?{
>> - ? ? u32 cyc = timer_read();
>> - ? ? return cyc_to_sched_clock(&cd, cyc, (u32)~0);
>> -}
>> -
>> -static void notrace mmp_update_sched_clock(void)
>> -{
>> - ? ? u32 cyc = timer_read();
>> - ? ? update_sched_clock(&cd, cyc, (u32)~0);
>> + ? ? return timer_read();
>> ?}
>>
>> ?static irqreturn_t timer_interrupt(int irq, void *dev_id)
>> @@ -201,7 +192,7 @@ void __init timer_init(int irq)
>> ?{
>> ? ? ? timer_config();
>>
>> - ? ? init_sched_clock(&cd, mmp_update_sched_clock, 32, CLOCK_TICK_RATE);
>> + ? ? init_sched_clock(mmp_sched_clock_read, 32, CLOCK_TICK_RATE);
>>
>> ? ? ? ckevt.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt.shift);
>> ? ? ? ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt);
>> diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
>> index a183777..e6df086 100644
>> --- a/arch/arm/mach-omap1/time.c
>> +++ b/arch/arm/mach-omap1/time.c
>> @@ -190,30 +190,9 @@ static __init void omap_init_mpu_timer(unsigned long rate)
>> ? * ---------------------------------------------------------------------------
>> ? */
>>
>> -static DEFINE_CLOCK_DATA(cd);
>> -
>> -static inline unsigned long long notrace _omap_mpu_sched_clock(void)
>> -{
>> - ? ? u32 cyc = ~omap_mpu_timer_read(1);
>> - ? ? return cyc_to_sched_clock(&cd, cyc, (u32)~0);
>> -}
>> -
>> -#ifndef CONFIG_OMAP_32K_TIMER
>> -unsigned long long notrace sched_clock(void)
>> -{
>> - ? ? return _omap_mpu_sched_clock();
>> -}
>> -#else
>> -static unsigned long long notrace omap_mpu_sched_clock(void)
>> -{
>> - ? ? return _omap_mpu_sched_clock();
>> -}
>> -#endif
>> -
>> -static void notrace mpu_update_sched_clock(void)
>> +static u32 notrace omap_mpu_sched_clock_read(void)
>> ?{
>> - ? ? u32 cyc = ~omap_mpu_timer_read(1);
>> - ? ? update_sched_clock(&cd, cyc, (u32)~0);
>> + ? ? return = ~omap_mpu_timer_read(1);
>> ?}
>>
>> ?static void __init omap_init_clocksource(unsigned long rate)
>> @@ -223,7 +202,7 @@ static void __init omap_init_clocksource(unsigned long rate)
>> ? ? ? ? ? ? ? ? ? ? ? "%s: can't register clocksource!\n";
>>
>> ? ? ? omap_mpu_timer_start(1, ~0, 1);
>> - ? ? init_sched_clock(&cd, mpu_update_sched_clock, 32, rate);
>> + ? ? init_sched_clock(omap_mpu_sched_clock_read, 32, rate);
>>
>> ? ? ? if (clocksource_mmio_init(&timer->read_tim, "mpu_timer2", rate,
>> ? ? ? ? ? ? ? ? ? ? ? 300, 32, clocksource_mmio_readl_down))
>> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
>> index cf1de7d..a0d4199 100644
>> --- a/arch/arm/mach-omap2/timer.c
>> +++ b/arch/arm/mach-omap2/timer.c
>> @@ -248,7 +248,6 @@ static struct omap_dm_timer clksrc;
>> ?/*
>> ? * clocksource
>> ? */
>> -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);
>> @@ -262,23 +261,9 @@ static struct clocksource clocksource_gpt = {
>> ? ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS,
>> ?};
>>
>> -static void notrace dmtimer_update_sched_clock(void)
>> +static u32 notrace dmtimer_sched_clock_read(void)
>> ?{
>> - ? ? u32 cyc;
>> -
>> - ? ? cyc = __omap_dm_timer_read_counter(clksrc.io_base, 1);
>> -
>> - ? ? update_sched_clock(&cd, cyc, (u32)~0);
>> -}
>> -
>> -unsigned long long notrace sched_clock(void)
>> -{
>> - ? ? u32 cyc = 0;
>> -
>> - ? ? if (clksrc.reserved)
>> - ? ? ? ? ? ? cyc = __omap_dm_timer_read_counter(clksrc.io_base, 1);
>> -
>> - ? ? return cyc_to_sched_clock(&cd, cyc, (u32)~0);
>> + ? ? return __omap_dm_timer_read_counter(clksrc.io_base, 1);
>> ?}
>>
>> ?/* Setup free-running counter for clocksource */
>> @@ -295,7 +280,7 @@ static void __init omap2_gp_clocksource_init(int gptimer_id,
>>
>> ? ? ? __omap_dm_timer_load_start(clksrc.io_base,
>> ? ? ? ? ? ? ? ? ? ? ? OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
>> - ? ? init_sched_clock(&cd, dmtimer_update_sched_clock, 32, clksrc.rate);
>> + ? ? init_sched_clock(dmtimer_sched_clock_read, 32, clksrc.rate);
>>
>> ? ? ? if (clocksource_register_hz(&clocksource_gpt, clksrc.rate))
>> ? ? ? ? ? ? ? pr_err("Could not register clocksource %s\n",
>> diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
>> index de68470..ff0b1a6 100644
>> --- a/arch/arm/mach-pxa/time.c
>> +++ b/arch/arm/mach-pxa/time.c
>> @@ -24,26 +24,9 @@
>> ?#include <asm/sched_clock.h>
>> ?#include <mach/regs-ost.h>
>>
>> -/*
>> - * This is PXA's sched_clock implementation. This has a resolution
>> - * of at least 308 ns and a maximum value of 208 days.
>> - *
>> - * The return value is guaranteed to be monotonic in that range as
>> - * long as there is always less than 582 seconds between successive
>> - * calls to sched_clock() which should always be the case in practice.
>> - */
>> -static DEFINE_CLOCK_DATA(cd);
>> -
>> -unsigned long long notrace sched_clock(void)
>> -{
>> - ? ? u32 cyc = OSCR;
>> - ? ? return cyc_to_sched_clock(&cd, cyc, (u32)~0);
>> -}
>> -
>> -static void notrace pxa_update_sched_clock(void)
>> +static u32 notrace pxa_sched_clock_read(void)
>> ?{
>> - ? ? u32 cyc = OSCR;
>> - ? ? update_sched_clock(&cd, cyc, (u32)~0);
>> + ? ? return OSCR;
>> ?}
>>
>>
>> @@ -119,7 +102,7 @@ static void __init pxa_timer_init(void)
>> ? ? ? OIER = 0;
>> ? ? ? OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
>>
>> - ? ? init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate);
>> + ? ? init_sched_clock(pxa_sched_clock_read, 32, clock_tick_rate);
>>
>> ? ? ? clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4);
>> ? ? ? ckevt_pxa_osmr0.max_delta_ns =
>> diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
>> index fa66024..ebaa64e 100644
>> --- a/arch/arm/mach-sa1100/time.c
>> +++ b/arch/arm/mach-sa1100/time.c
>> @@ -20,29 +20,9 @@
>> ?#include <asm/sched_clock.h>
>> ?#include <mach/hardware.h>
>>
>> -/*
>> - * This is the SA11x0 sched_clock implementation.
>> - */
>> -static DEFINE_CLOCK_DATA(cd);
>> -
>> -/*
>> - * Constants generated by clocks_calc_mult_shift(m, s, 3.6864MHz,
>> - * NSEC_PER_SEC, 60).
>> - * This gives a resolution of about 271ns and a wrap period of about 19min.
>> - */
>> -#define SC_MULT ? ? ? ? ? ? ?2275555556u
>> -#define SC_SHIFT ? ? 23
>> -
>> -unsigned long long notrace sched_clock(void)
>> -{
>> - ? ? u32 cyc = OSCR;
>> - ? ? return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
>> -}
>> -
>> -static void notrace sa1100_update_sched_clock(void)
>> +static u32 notrace sa1100_sched_clock_read(void)
>> ?{
>> - ? ? u32 cyc = OSCR;
>> - ? ? update_sched_clock(&cd, cyc, (u32)~0);
>> + ? ? return OSCR;
>> ?}
>>
>> ?#define MIN_OSCR_DELTA 2
>> @@ -109,8 +89,7 @@ static void __init sa1100_timer_init(void)
>> ? ? ? OIER = 0;
>> ? ? ? OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
>>
>> - ? ? init_fixed_sched_clock(&cd, sa1100_update_sched_clock, 32,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ?3686400, SC_MULT, SC_SHIFT);
>> + ? ? init_sched_clock(sa1100_sched_clock_read, 32, 3686400);
>>
>> ? ? ? clockevents_calc_mult_shift(&ckevt_sa1100_osmr0, 3686400, 4);
>> ? ? ? ckevt_sa1100_osmr0.max_delta_ns =
>> diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
>> index 9035042..fdf1e12 100644
>> --- a/arch/arm/mach-tegra/timer.c
>> +++ b/arch/arm/mach-tegra/timer.c
>> @@ -106,25 +106,9 @@ static struct clock_event_device tegra_clockevent = {
>> ? ? ? .set_mode ? ? ? = tegra_timer_set_mode,
>> ?};
>>
>> -static DEFINE_CLOCK_DATA(cd);
>> -
>> -/*
>> - * Constants generated by clocks_calc_mult_shift(m, s, 1MHz, NSEC_PER_SEC, 60).
>> - * This gives a resolution of about 1us and a wrap period of about 1h11min.
>> - */
>> -#define SC_MULT ? ? ? ? ? ? ?4194304000u
>> -#define SC_SHIFT ? ? 22
>> -
>> -unsigned long long notrace sched_clock(void)
>> -{
>> - ? ? u32 cyc = timer_readl(TIMERUS_CNTR_1US);
>> - ? ? return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
>> -}
>> -
>> -static void notrace tegra_update_sched_clock(void)
>> +static u32 notrace tegra_sched_clock_read(void)
>> ?{
>> - ? ? u32 cyc = timer_readl(TIMERUS_CNTR_1US);
>> - ? ? update_sched_clock(&cd, cyc, (u32)~0);
>> + ? ? return timer_readl(TIMERUS_CNTR_1US);
>> ?}
>>
>> ?/*
>> @@ -218,8 +202,7 @@ static void __init tegra_init_timer(void)
>> ? ? ? ? ? ? ? WARN(1, "Unknown clock rate");
>> ? ? ? }
>>
>> - ? ? init_fixed_sched_clock(&cd, tegra_update_sched_clock, 32,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ?1000000, SC_MULT, SC_SHIFT);
>> + ? ? init_sched_clock(tegra_sched_clock_read, 32, 1000000);
>>
>> ? ? ? if (clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US,
>> ? ? ? ? ? ? ? "timer_us", 1000000, 300, 32, clocksource_mmio_readl_up)) {
>> diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c
>> index 5f51bde..2301f71 100644
>> --- a/arch/arm/mach-u300/timer.c
>> +++ b/arch/arm/mach-u300/timer.c
>> @@ -330,25 +330,9 @@ static struct irqaction u300_timer_irq = {
>> ? ? ? .handler ? ? ? ?= u300_timer_interrupt,
>> ?};
>>
>> -/*
>> - * Override the global weak sched_clock symbol with this
>> - * local implementation which uses the clocksource to get some
>> - * better resolution when scheduling the kernel. We accept that
>> - * this wraps around for now, since it is just a relative time
>> - * stamp. (Inspired by OMAP implementation.)
>> - */
>> -static DEFINE_CLOCK_DATA(cd);
>> -
>> -unsigned long long notrace sched_clock(void)
>> -{
>> - ? ? u32 cyc = readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC);
>> - ? ? return cyc_to_sched_clock(&cd, cyc, (u32)~0);
>> -}
>> -
>> -static void notrace u300_update_sched_clock(void)
>> +static u32 notrace u300_sched_clock_read(void)
>> ?{
>> - ? ? u32 cyc = readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC);
>> - ? ? update_sched_clock(&cd, cyc, (u32)~0);
>> + ? ? return readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC);
>> ?}
>>
>>
>> @@ -366,7 +350,7 @@ static void __init u300_timer_init(void)
>> ? ? ? clk_enable(clk);
>> ? ? ? rate = clk_get_rate(clk);
>>
>> - ? ? init_sched_clock(&cd, u300_update_sched_clock, 32, rate);
>> + ? ? init_sched_clock(u300_sched_clock_read, 32, rate);
>>
>> ? ? ? /*
>> ? ? ? ?* Disable the "OS" and "DD" timers - these are designed for Symbian!
>> diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
>> index 7cdc516..b038636 100644
>> --- a/arch/arm/plat-iop/time.c
>> +++ b/arch/arm/plat-iop/time.c
>> @@ -51,21 +51,12 @@ static struct clocksource iop_clocksource = {
>> ? ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS,
>> ?};
>>
>> -static DEFINE_CLOCK_DATA(cd);
>> -
>> ?/*
>> ? * IOP sched_clock() implementation via its clocksource.
>> ? */
>> -unsigned long long notrace sched_clock(void)
>> -{
>> - ? ? u32 cyc = 0xffffffffu - read_tcr1();
>> - ? ? return cyc_to_sched_clock(&cd, cyc, (u32)~0);
>> -}
>> -
>> -static void notrace iop_update_sched_clock(void)
>> +static u32 notrace iop_sched_clock_read(void)
>> ?{
>> - ? ? u32 cyc = 0xffffffffu - read_tcr1();
>> - ? ? update_sched_clock(&cd, cyc, (u32)~0);
>> + ? ? return cyc = 0xffffffffu - read_tcr1();
>> ?}
>>
>> ?/*
>> @@ -151,7 +142,7 @@ void __init iop_init_time(unsigned long tick_rate)
>> ?{
>> ? ? ? u32 timer_ctl;
>>
>> - ? ? init_sched_clock(&cd, iop_update_sched_clock, 32, tick_rate);
>> + ? ? init_sched_clock(iop_sched_clock_read, 32, tick_rate);
>>
>> ? ? ? ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ);
>> ? ? ? iop_tick_rate = tick_rate;
>> diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
>> index 4b0fe28..b74f721 100644
>> --- a/arch/arm/plat-mxc/time.c
>> +++ b/arch/arm/plat-mxc/time.c
>> @@ -108,18 +108,9 @@ static void gpt_irq_acknowledge(void)
>>
>> ?static void __iomem *sched_clock_reg;
>>
>> -static DEFINE_CLOCK_DATA(cd);
>> -unsigned long long notrace sched_clock(void)
>> +static u32 notrace mxc_sched_clock_read(void)
>> ?{
>> - ? ? cycle_t cyc = sched_clock_reg ? __raw_readl(sched_clock_reg) : 0;
>> -
>> - ? ? return cyc_to_sched_clock(&cd, cyc, (u32)~0);
>> -}
>> -
>> -static void notrace mxc_update_sched_clock(void)
>> -{
>> - ? ? cycle_t cyc = sched_clock_reg ? __raw_readl(sched_clock_reg) : 0;
>> - ? ? update_sched_clock(&cd, cyc, (u32)~0);
>> + ? ? return __raw_readl(sched_clock_reg);
>> ?}
>>
>> ?static int __init mxc_clocksource_init(struct clk *timer_clk)
>> @@ -129,7 +120,7 @@ static int __init mxc_clocksource_init(struct clk *timer_clk)
>>
>> ? ? ? sched_clock_reg = reg;
>>
>> - ? ? init_sched_clock(&cd, mxc_update_sched_clock, 32, c);
>> + ? ? init_sched_clock(mxc_sched_clock_read, 32, c);
>> ? ? ? return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32,
>> ? ? ? ? ? ? ? ? ? ? ? clocksource_mmio_readl_up);
>> ?}
>> diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
>> index ef74e15..6e38ed1 100644
>> --- a/arch/arm/plat-nomadik/timer.c
>> +++ b/arch/arm/plat-nomadik/timer.c
>> @@ -25,28 +25,9 @@
>>
>> ?void __iomem *mtu_base; /* Assigned by machine code */
>>
>> -/*
>> - * Override the global weak sched_clock symbol with this
>> - * local implementation which uses the clocksource to get some
>> - * better resolution when scheduling the kernel.
>> - */
>> -static DEFINE_CLOCK_DATA(cd);
>> -
>> -unsigned long long notrace sched_clock(void)
>> -{
>> - ? ? u32 cyc;
>> -
>> - ? ? if (unlikely(!mtu_base))
>> - ? ? ? ? ? ? return 0;
>> -
>> - ? ? cyc = -readl(mtu_base + MTU_VAL(0));
>> - ? ? return cyc_to_sched_clock(&cd, cyc, (u32)~0);
>> -}
>> -
>> -static void notrace nomadik_update_sched_clock(void)
>> +static u32 notrace nomadik_sched_clock_read(void)
>> ?{
>> - ? ? u32 cyc = -readl(mtu_base + MTU_VAL(0));
>> - ? ? update_sched_clock(&cd, cyc, (u32)~0);
>> + ? ? return -readl(mtu_base + MTU_VAL(0));
>> ?}
>>
>> ?/* Clockevent device: use one-shot mode */
>> @@ -154,7 +135,7 @@ void __init nmdk_timer_init(void)
>> ? ? ? ? ? ? ? pr_err("timer: failed to initialize clock source %s\n",
>> ? ? ? ? ? ? ? ? ? ? ?"mtu_0");
>>
>> - ? ? init_sched_clock(&cd, nomadik_update_sched_clock, 32, rate);
>> + ? ? init_sched_clock(nomadik_sched_clock_read, 32, rate);
>>
>> ? ? ? /* Timer 1 is used for events */
>>
>> diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
>> index a6cbb71..1faa7ce 100644
>> --- a/arch/arm/plat-omap/counter_32k.c
>> +++ b/arch/arm/plat-omap/counter_32k.c
>> @@ -37,41 +37,9 @@ static void __iomem *timer_32k_base;
>>
>> ?#define OMAP16XX_TIMER_32K_SYNCHRONIZED ? ? ? ? ? ? ?0xfffbc410
>>
>> -/*
>> - * Returns current time from boot in nsecs. It's OK for this to wrap
>> - * around for now, as it's just a relative time stamp.
>> - */
>> -static DEFINE_CLOCK_DATA(cd);
>> -
>> -/*
>> - * Constants generated by clocks_calc_mult_shift(m, s, 32768, NSEC_PER_SEC, 60).
>> - * This gives a resolution of about 30us and a wrap period of about 36hrs.
>> - */
>> -#define SC_MULT ? ? ? ? ? ? ?4000000000u
>> -#define SC_SHIFT ? ? 17
>> -
>> -static inline unsigned long long notrace _omap_32k_sched_clock(void)
>> -{
>> - ? ? u32 cyc = timer_32k_base ? __raw_readl(timer_32k_base) : 0;
>> - ? ? return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
>> -}
>> -
>> -#if defined(CONFIG_OMAP_32K_TIMER) && !defined(CONFIG_OMAP_MPU_TIMER)
>> -unsigned long long notrace sched_clock(void)
>> -{
>> - ? ? return _omap_32k_sched_clock();
>> -}
>> -#else
>> -unsigned long long notrace omap_32k_sched_clock(void)
>> -{
>> - ? ? return _omap_32k_sched_clock();
>> -}
>> -#endif
>> -
>> -static void notrace omap_update_sched_clock(void)
>> +static inline u32 notrace omap_32k_sched_clock_read(void)
>> ?{
>> - ? ? u32 cyc = timer_32k_base ? __raw_readl(timer_32k_base) : 0;
>> - ? ? update_sched_clock(&cd, cyc, (u32)~0);
>> + ? ? return __raw_readl(timer_32k_base);
>> ?}
>>
>> ?/**
>> @@ -147,8 +115,7 @@ int __init omap_init_clocksource_32k(void)
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? clocksource_mmio_readl_up))
>> ? ? ? ? ? ? ? ? ? ? ? printk(err, "32k_counter");
>>
>> - ? ? ? ? ? ? init_fixed_sched_clock(&cd, omap_update_sched_clock, 32,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?32768, SC_MULT, SC_SHIFT);
>> + ? ? ? ? ? ? init_sched_clock(omap_32k_sched_clock_read, 32, 32768);
>> ? ? ? }
>> ? ? ? return 0;
>> ?}
>> diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c
>> index 69a6136..34e8224 100644
>> --- a/arch/arm/plat-orion/time.c
>> +++ b/arch/arm/plat-orion/time.c
>> @@ -60,24 +60,14 @@ static u32 ticks_per_jiffy;
>> ? * Orion's sched_clock implementation. It has a resolution of
>> ? * at least 7.5ns (133MHz TCLK).
>> ? */
>> -static DEFINE_CLOCK_DATA(cd);
>> -
>> -unsigned long long notrace sched_clock(void)
>> -{
>> - ? ? u32 cyc = ~readl(timer_base + TIMER0_VAL_OFF);
>> - ? ? return cyc_to_sched_clock(&cd, cyc, (u32)~0);
>> -}
>> -
>> -
>> -static void notrace orion_update_sched_clock(void)
>> +static u32 notrace orion_sched_clock_read(void)
>> ?{
>> - ? ? u32 cyc = ~readl(timer_base + TIMER0_VAL_OFF);
>> - ? ? update_sched_clock(&cd, cyc, (u32)~0);
>> + ? ? return = ~readl(timer_base + TIMER0_VAL_OFF);
>> ?}
>>
>> ?static void __init setup_sched_clock(unsigned long tclk)
>> ?{
>> - ? ? init_sched_clock(&cd, orion_update_sched_clock, 32, tclk);
>> + ? ? init_sched_clock(orion_sched_clock_read, 32, tclk);
>> ?}
>>
>> ?/*
>> diff --git a/arch/arm/plat-s5p/s5p-time.c b/arch/arm/plat-s5p/s5p-time.c
>> index c833e7b..6fc1121 100644
>> --- a/arch/arm/plat-s5p/s5p-time.c
>> +++ b/arch/arm/plat-s5p/s5p-time.c
>> @@ -314,33 +314,10 @@ static void __iomem *s5p_timer_reg(void)
>> ? ? ? return S3C_TIMERREG(offset);
>> ?}
>>
>> -/*
>> - * Override the global weak sched_clock symbol with this
>> - * local implementation which uses the clocksource to get some
>> - * better resolution when scheduling the kernel. We accept that
>> - * this wraps around for now, since it is just a relative time
>> - * stamp. (Inspired by U300 implementation.)
>> - */
>> -static DEFINE_CLOCK_DATA(cd);
>> -
>> -unsigned long long notrace sched_clock(void)
>> +static u32 notrace s5p_sched_clock_read(void)
>> ?{
>> ? ? ? void __iomem *reg = s5p_timer_reg();
>> -
>> - ? ? if (!reg)
>> - ? ? ? ? ? ? return 0;
>> -
>> - ? ? return cyc_to_sched_clock(&cd, ~__raw_readl(reg), (u32)~0);
>> -}
>> -
>> -static void notrace s5p_update_sched_clock(void)
>> -{
>> - ? ? void __iomem *reg = s5p_timer_reg();
>> -
>> - ? ? if (!reg)
>> - ? ? ? ? ? ? return;
>> -
>> - ? ? update_sched_clock(&cd, ~__raw_readl(reg), (u32)~0);
>> + ? ? return ~__raw_readl(reg);
>> ?}
>>
>> ?static void __init s5p_clocksource_init(void)
>> @@ -358,7 +335,7 @@ static void __init s5p_clocksource_init(void)
>> ? ? ? s5p_time_setup(timer_source.source_id, TCNT_MAX);
>> ? ? ? s5p_time_start(timer_source.source_id, PERIODIC);
>>
>> - ? ? init_sched_clock(&cd, s5p_update_sched_clock, 32, clock_rate);
>> + ? ? init_sched_clock(s5p_sched_clock_read, 32, clock_rate);
>>
>> ? ? ? if (clocksource_mmio_init(s5p_timer_reg(), "s5p_clocksource_timer",
>> ? ? ? ? ? ? ? ? ? ? ? clock_rate, 250, 32, clocksource_mmio_readl_down))
>> diff --git a/arch/arm/plat-versatile/sched-clock.c b/arch/arm/plat-versatile/sched-clock.c
>> index 3d6a4c2..d9d5ba4 100644
>> --- a/arch/arm/plat-versatile/sched-clock.c
>> +++ b/arch/arm/plat-versatile/sched-clock.c
>> @@ -24,35 +24,15 @@
>> ?#include <asm/sched_clock.h>
>> ?#include <plat/sched_clock.h>
>>
>> -static DEFINE_CLOCK_DATA(cd);
>> ?static void __iomem *ctr;
>>
>> -/*
>> - * Constants generated by clocks_calc_mult_shift(m, s, 24MHz, NSEC_PER_SEC, 60).
>> - * This gives a resolution of about 41ns and a wrap period of about 178s.
>> - */
>> -#define SC_MULT ? ? ? ? ? ? ?2796202667u
>> -#define SC_SHIFT ? ? 26
>> -
>> -unsigned long long notrace sched_clock(void)
>> -{
>> - ? ? if (ctr) {
>> - ? ? ? ? ? ? u32 cyc = readl(ctr);
>> - ? ? ? ? ? ? return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SC_MULT, SC_SHIFT);
>> - ? ? } else
>> - ? ? ? ? ? ? return 0;
>> -}
>> -
>> -static void notrace versatile_update_sched_clock(void)
>> +static u32 notrace versatile_sched_clock_read(void)
>> ?{
>> - ? ? u32 cyc = readl(ctr);
>> - ? ? update_sched_clock(&cd, cyc, (u32)~0);
>> + ? ? return readl(ctr);
>> ?}
>>
>> ?void __init versatile_sched_clock_init(void __iomem *reg, unsigned long rate)
>> ?{
>> ? ? ? ctr = reg;
>> - ? ? init_fixed_sched_clock(&cd, versatile_update_sched_clock,
>> - ? ? ? ? ? ? ? ? ? ? ? ? ? ?32, rate, SC_MULT, SC_SHIFT);
>> + ? ? init_sched_clock(versatile_sched_clock_read, 32, rate);
>> ?}
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
^ permalink raw reply
* [PATCH] arm/mxs: PHYS_OFFSET can not be defined in platform any longer
From: Shawn Guo @ 2011-09-23 7:49 UTC (permalink / raw)
To: linux-arm-kernel
Since ARM_PATCH_PHYS_VIRT has been globally enabled by default,
PHYS_OFFSET can not be defined in platform any longer. Otherwise,
we will run into the following warning.
arch/arm/include/asm/memory.h:156:0: warning: "PHYS_OFFSET" redefined
arch/arm/mach-mxs/include/mach/memory.h:22:0: note: this is the location of the previous definition
Change PHYS_OFFSET to PLAT_PHYS_OFFSET to avoid the warning.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
Yes, I know that Nicolas has a big patch to remove mach/memory.h
globally. But rmk has not acked/pulled it. This patch is posted
just for reminding that if Nicolas' patch does not hit v3.2, we will
have to merge this patch to save a fix patch to remove the warning.
arch/arm/mach-mxs/include/mach/memory.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
index b5420a5..0618ae2 100644
--- a/arch/arm/mach-mxs/include/mach/memory.h
+++ b/arch/arm/mach-mxs/include/mach/memory.h
@@ -19,6 +19,6 @@
#ifndef __MACH_MXS_MEMORY_H__
#define __MACH_MXS_MEMORY_H__
-#define PHYS_OFFSET UL(0x40000000)
+#define PLAT_PHYS_OFFSET UL(0x40000000)
#endif /* __MACH_MXS_MEMORY_H__ */
--
1.7.4.1
^ permalink raw reply related
* [patch] ARM: smpboot: Enable interrupts after marking CPU online/active
From: Russell King - ARM Linux @ 2011-09-23 8:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110913175312.GB6267@n2100.arm.linux.org.uk>
On Tue, Sep 13, 2011 at 06:53:12PM +0100, Russell King - ARM Linux wrote:
> So, we must have the setting of CPU online _after_ we've setup the
> scheduler domain information etc - so the following is a strict
> ordering:
>
> 1. calibrate_delay()
> 2. smp_store_cpu_info()
> 3. set_cpu_online()
>
> Now, the question is do we need interrupts enabled to setup timers
> via percpu_timer_setup() and calibrate delay. Can we move enabling
> interrupts after smp_store_cpu_info(). IOW, instead of moving the
> setting of cpu online before all this, can we move notify_cpu_starting()
> and the enabling of _both_ interrupts after smp_store_cpu_info()...
> No idea at the moment.
And to make things worse... 4bd0fe1c78623062263cf5ae875fd484c5b8256d
has appeared in mainline today.
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c
index 7c2282c..df6ef1b 100644
--- a/arch/arm/mach-exynos4/platsmp.c
+++ b/arch/arm/mach-exynos4/platsmp.c
@@ -106,6 +106,8 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
*/
spin_lock(&boot_lock);
spin_unlock(&boot_lock);
+
+ set_cpu_online(cpu, true);
}
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
I think some work needs to be done to eliminate some of the dependencies
in this code so that we can have a *sane* order for bringup of secondary
CPUs.
I'm just going to sit on the fence and watch what platform people do
during the next merge window when the support for the topological
scheduler goes in.
^ permalink raw reply related
* [PATCH] ARM: futex: fix clobbering oldval
From: Will Deacon @ 2011-09-23 8:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316737129.6872.17.camel@puffmine-laptop>
On Fri, Sep 23, 2011 at 01:18:49AM +0100, mhban wrote:
> On Thu, 2011-09-22 at 18:26 +0100, Will Deacon wrote:
> >
> > It would have been nice to have been CC'd on this...
>
> Will not miss next time. Thanks.
Thanks. You can use scripts/get_maintainer.pl to get a list of people to
email.
> >
> > You shouldn't reference r5 directly here, but due to the way the futex code
> > is laid out, you can't add an extra output operand without converting the
> > code to use named arguments.
> >
> > I'll post a patch to do that.
> >
> > Will
>
> I'm not familiar with gcc inline, thanks for pointing it out.
There's a good guide for ARM here:
http://www.ethernut.de/en/documents/arm-inline-asm.html
> BTW, my last name is Ban not Ben.
Oops, I'll update my reported-by to spell that correctly.
Cheers,
Will
^ permalink raw reply
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