* [PATCH] dmaengine: add CSR SiRFprimaII DMAC driver
From: Barry Song @ 2011-09-16 9:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGsJ_4x4S+8d3xS+QTrjDpoxcHo3p7qArd7yFr=+h1vxSRvEpA@mail.gmail.com>
>>> +/* 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->regs + SIRFSOC_DMA_CH_INT);
>>> + ? ? while ((ch = fls(is) - 1) >= 0) {
>>> + ? ? ? ? ? ? is &= ~(1 << ch);
>>> + ? ? ? ? ? ? writel_relaxed(1 << ch, sdma->regs + 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);
>>> + ? ? }
>> Here you know which channel has triggered interrupt and you may pass
>> this info to your tasklet and avoid scanning again there
>
> ok. let me see.
we really know what channels have been trigger in irq. but we lose a
good way to transfer that to tasklet actually. if we place a flag in
schan data.
1. there can be more 1 channels triggers, then tasklet still need a for(...)
2. we actually need a lock between irq and tasklet. otherwise, new irq
coming in tasklet might change the flag.
so i think current way should be better.
>
>>
>>> +
>>> + ? ? /* Schedule tasklet */
>>> + ? ? tasklet_schedule(&sdma->tasklet);
>>> +
>>> + ? ? return IRQ_HANDLED;
>>> +}
>>> +
>>> +/* process completed descriptors */
>>> +static void sirfsoc_dma_process_completed(struct sirfsoc_dma *sdma)
>>> +{
>>> + ? ? dma_cookie_t last_cookie = 0;
>>> + ? ? struct sirfsoc_dma_chan *schan;
>>> + ? ? struct sirfsoc_dma_desc *mdesc;
>>> + ? ? struct dma_async_tx_descriptor *desc;
>>> + ? ? unsigned long flags;
>>> + ? ? LIST_HEAD(list);
>>> + ? ? int i;
>>> +
>>> + ? ? for (i = 0; i < sdma->dma.chancnt; i++) {
>>> + ? ? ? ? ? ? schan = &sdma->channels[i];
>>> +
>>> + ? ? ? ? ? ? /* Get all completed descriptors */
>>> + ? ? ? ? ? ? spin_lock_irqsave(&schan->lock, flags);
>> this will block interrupts, i dont see a reason why this should be used
>> here??
>
> ok. no irq is accessing completed list.
sorry. after reading more carefully, we actually need this lock since
irq will move finished active node to completed list. we need to keep
the completed safe.
i have fixed other issues and used jassi's v1 patch (generic xfer) and
will send v2.
Thanks
barry
^ permalink raw reply
* [PATCH 0/7] ASoC: ep93xx: convert to use snd_soc_register_card()
From: Mark Brown @ 2011-09-16 9:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110913174431.GA2651@mwesterb-mobl.ger.corp.intel.com>
On Tue, Sep 13, 2011 at 08:44:31PM +0300, Mika Westerberg wrote:
> If Mark is ok with these and Reviewed-by from Ryan is enough then I guess
> these can be merged in the ASoC tree now. On the other hand if formal acks
> from ep93xx maintainers are needed, then these can wait until you come back
> from your vacation.
I've applied them all, thanks.
^ permalink raw reply
* [RFC PATCH 01/11] OMAP: TWL: Clean up mode and ops mask passed from board files
From: Rajendra Nayak @ 2011-09-16 9:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110916085732.GB22062@opensource.wolfsonmicro.com>
On Friday 16 September 2011 02:27 PM, Mark Brown wrote:
> On Fri, Sep 16, 2011 at 12:41:53PM +0530, Rajendra Nayak wrote:
>> On Thursday 15 September 2011 07:02 PM, Mark Brown wrote:
>>> On Thu, Sep 15, 2011 at 04:51:57PM +0530, Rajendra Nayak wrote:
>
>>>> There is no need for all the board files to pass this information
>>>> additionally, when the driver already sets them by default.
>
>>> "the driver"? This sounds very buggy...
>
>> Yeah, the driver currently sets some default based on what
>> the chip itself supports and completely ignores the board
>> inputs.
>> How about the driver using the defaults and letting the boards
>> override it (if it ever wants to)?
>> Currently none of the boards (using any of the twl
>> regulators) seem to override the defaults and that way a lot of
>> this duplication in board files could be avoided.
>
> No, this is just plain buggy. It's fine for OMAP to have some common
> stuff that the board reference but if the drivers are doing this that's
> bad. The drivers and framework shouldn't touch the hardware unless the
> board says it's OK.
fair enough, I'll fix up the driver then.
^ permalink raw reply
* [RFC PATCH 04/11] omap4: SDP: Pass regulator_init_data from DT
From: Rajendra Nayak @ 2011-09-16 9:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110916090026.GD22062@opensource.wolfsonmicro.com>
On Friday 16 September 2011 02:30 PM, Mark Brown wrote:
> On Fri, Sep 16, 2011 at 12:47:05PM +0530, Rajendra Nayak wrote:
>> On Thursday 15 September 2011 07:16 PM, Mark Brown wrote:
>>> On Thu, Sep 15, 2011 at 04:52:00PM +0530, Rajendra Nayak wrote:
>
>>>> +Required properties:
>>>> +- compatible: Must be "regulator","ti,twl-reg";
>
>>> I'd expect listings for the specific chips too.
>
>> I just did'nt do that because we have just one driver for
>> all twl chips (twl4030/twl6030/twl6025) and there seems to be
>> no real need to identify specific chips while we could
>> do knowing just the chip family.
>
> The driver can bind to as many names as it likes.
makes sense, I'll add one per chip variant.
>
>>>> + xyz-regulator: regulator at 0 {
>>>> + compatible = "regulator","ti,twl-reg";
>>>> + ti,reg-id =<37>; /* TWL6030_REG_VAUX1_6030 */
>
>>> These magic numbers are *very* Linux specific, we should have a better
>>> way of specifying regulators - I'd off the top of my head expect that
>>> the compatible property would identify the regulator.
>
>> The driver seems to use a per-regulator table, and it uses the above
>> id to indexed into it. I could probably do it with the compatible
>
> I know what the driver is doing, the problem is that it's very much
> specific to Linux (and Linux may change the numbers at some point).
>
>> property, but that would mean I have a compatible for *each* regulator
>> instance, like "ti,twl-reg-vaux1", "ti,twl-reg-vmmc" etc.
>> Does that sound reasonable?
>
> Yes.
^ permalink raw reply
* [RFC PATCH 06/11] DT: regulator: Helper routine to extract fixed_voltage_config
From: Rajendra Nayak @ 2011-09-16 9:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110916090123.GE22062@opensource.wolfsonmicro.com>
On Friday 16 September 2011 02:31 PM, Mark Brown wrote:
> On Fri, Sep 16, 2011 at 12:49:17PM +0530, Rajendra Nayak wrote:
>> On Thursday 15 September 2011 07:20 PM, Mark Brown wrote:
>>> On Thu, Sep 15, 2011 at 04:52:02PM +0530, Rajendra Nayak wrote:
>
>>>> +# For fixed voltage regulators
>>>> +- supply-name: Name of the regulator supply
>>>> +- microvolts: Output voltage of regulator
>>>> +- gpio: gpio to use for enable control
>>>> +- startup-delay: startup time in microseconds
>>>> +- enable-high: Polarity of enable GPIO, 1 = Active High, 0 = Active low
>>>> +- enabled-at-boot: 1 = yes, 0 = no
>
>>> Much of this is specific to the Linux fixed voltage regulator driver
>>> rather than a generic regulator with a fixed voltage.
>
>> So how should these non-generic things be handled through device
>> tree? Should they never be part of dt or should the bindings just be
>> defined such that its clear they are linux specific?
>
> Having them be part of the fixed voltage regulator bindings would be
> fine, the problem is that you're adding this in framework code not in a
> driver.
agree, will make the bindings fixed voltage regulator specific.
^ permalink raw reply
* [PATCH v15 06/12] OMAP: dmtimer: switch-over to platform device driver
From: DebBarma, Tarun Kanti @ 2011-09-16 9:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAC83ZvKGoucZ=xQSa7GEk7Gg8jcFBQE==1a6m4=+nzDRrsw+jw@mail.gmail.com>
[...]
>>> 1. Modify the inline access functions to take the PEND and others
>>> ? ?if needed registers as a parameter
>>>
>>> 2. Modify mach-omap2/timer.c to initialize the PEND and others
>>> ? ?in the SoC specific timer_init function
Just to make my understanding complete, need some clarifications:
As we would end up modifying almost all inline functions, what naming
convention should we follow for the parameters? For instance, PEND
is related to TWPS register. So are you suggesting using parameter
names related to respective registers in each inline functions?
If that is the case we would end up declaring lot of local variables along
with PEND. Instead, we could very well have just two variables to
represent functional and interrupt offsets.
Also, in plat-omap/dmtimer.c, timer_regs{} stores the register values and
not the register offsets. Therefore, we would not be able to pass as
parameters, timer->context.<x> ... etc.
Please let me know if I am off-track in my understanding.
Thanks.
--
Tarun
[...]
^ permalink raw reply
* [PATCH 5/5] ARM: gic: add OF based initialization
From: Thomas Abraham @ 2011-09-16 9:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E71F593.2040903@gmail.com>
Hi Rob,
On 15 September 2011 18:24, Rob Herring <robherring2@gmail.com> wrote:
> On 09/15/2011 02:55 AM, Thomas Abraham wrote:
>> Hi Rob,
>>
>> On 14 September 2011 22:01, Rob Herring <robherring2@gmail.com> wrote:
>>> From: Rob Herring <rob.herring@calxeda.com>
>>>
>>> This adds gic initialization using device tree data. The initialization
>>> functions are intended to be called by a generic OF interrupt
>>> controller parsing function once the right pieces are in place.
>>>
>>> PPIs are handled using 3rd cell of interrupts properties to specify the cpu
>>> mask the PPI is assigned to.
>>>
>>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>>> ---
>>> ?Documentation/devicetree/bindings/arm/gic.txt | ? 53 ++++++++++++++++++++++++
>>> ?arch/arm/common/gic.c ? ? ? ? ? ? ? ? ? ? ? ? | ? 55 +++++++++++++++++++++++--
>>> ?arch/arm/include/asm/hardware/gic.h ? ? ? ? ? | ? 10 +++++
>>> ?3 files changed, 114 insertions(+), 4 deletions(-)
>>> ?create mode 100644 Documentation/devicetree/bindings/arm/gic.txt
>>
>> [...]
>>
>>
>>> diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
>>> index d1ccc72..14de380 100644
>>> --- a/arch/arm/common/gic.c
>>> +++ b/arch/arm/common/gic.c
>>
>> [...]
>>
>>> +void __init gic_of_init(struct device_node *node, struct device_node *parent)
>>> +{
>>> + ? ? ? void __iomem *cpu_base;
>>> + ? ? ? void __iomem *dist_base;
>>> + ? ? ? int irq;
>>> + ? ? ? struct irq_domain *domain = &gic_data[gic_cnt].domain;
>>> +
>>> + ? ? ? if (WARN_ON(!node))
>>> + ? ? ? ? ? ? ? return;
>>> +
>>> + ? ? ? dist_base = of_iomap(node, 0);
>>> + ? ? ? WARN(!dist_base, "unable to map gic dist registers\n");
>>> +
>>> + ? ? ? cpu_base = of_iomap(node, 1);
>>> + ? ? ? WARN(!cpu_base, "unable to map gic cpu registers\n");
>>> +
>>> + ? ? ? domain->nr_irq = gic_irq_count(dist_base);
>>> + ? ? ? domain->irq_base = irq_alloc_descs(-1, 0, domain->nr_irq, numa_node_id());
>>
>> For exynos4, all the interrupts originating from GIC are statically
>> mapped to start from 32 in the linux virq space (GIC SPI interrupts
>> start from 64). In the above code, since irq_base would be 0 for
>> exynos4, the interrupt mapping is not working correctly. In your
>> previous version of the patch, you have given a option to the platform
>> code to choose the offset. Could that option be added to this series
>> also. Or a provision to use platform specific translate function
>> instead of the irq_domain_simple translator.
>>
>
> So I guess you have the A9 external nIRQ hooked up to another
> controller? Why can't the 0-31 interrupts get mapped to after the gic
> interrupts? Ultimately we want h/w irq numbers completely decoupled from
> linux irq numbers. So you will want to put that controller in devicetree
> and have an DT init function for it as well.
There are chained interrupt handlers mapped in between linux irq
number 0 to 31. So the offset for GIC interrupts was set to 32 (SGI[0]
= 32). The interrupt chaining for the interrupts mapped between 0 to
31 seems unnecessary though. I will try removing them and check.
>
> In anycase, there's a simple solution. You just need a call to
> irq_alloc_descs to reserve the first 32 interrupts before calling
> of_irq_init.
>
> Rob
>
Thanks for your comments.
Regards,
Thomas.
^ permalink raw reply
* [RFC PATCH 1/3] genirq: add support for per-cpu dev_id interrupts
From: Marc Zyngier @ 2011-09-16 9:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1109152207010.2723@ionos>
On 15/09/11 23:49, Thomas Gleixner wrote:
> Marc,
>
> On Thu, 15 Sep 2011, Marc Zyngier wrote:
>>
>> Based on an initial patch by Thomas Gleixner.
>
> Was more an idea than a patch :)
Almost the same thing :)
>
>> + void *dev_id;
>> +#ifdef CONFIG_IRQ_PERCPU_DEVID
>> + void __percpu *percpu_dev_id;
>> +#endif
>
> Can we please avoid that ifdef and use an anon union ?
See my reply to Micha? on the same subject. Doing so breaks existing
code because of what looks like a GCC problem.
>
>> +#ifdef CONFIG_IRQ_PERCPU_DEVID
>> +static inline int irq_set_percpu_devid(unsigned int irq)
>
> Real function in kernel/irq/ please
I will then have to split it somehow, as anything that includes irq.h
and refers to a IRQ_* flag falls into the "GOT_YOU_MORON" trap...
>> +{
>> + struct irq_desc *desc = irq_to_desc(irq);
>> +
>> + if (!desc)
>> + return -EINVAL;
>> +
>> + if (!zalloc_cpumask_var(&desc->percpu_enabled, GFP_KERNEL))
>> + return -ENOMEM;
>
> What prevents that allocation happening more than once ?
Will fix.
>> + irq_set_status_flags(irq,
>> + IRQ_NOAUTOEN | IRQ_PER_CPU | IRQ_NOTHREAD |
>> + IRQ_NOPROBE | IRQ_PER_CPU_DEVID);
>> + return 0;
>> +}
>> +#endif
>> +
>> /* Handle dynamic irq creation and destruction */
>> extern unsigned int create_irq_nr(unsigned int irq_want, int node);
>> extern int create_irq(void);
>> diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
>> index 150134a..0b4419a 100644
>> --- a/include/linux/irqdesc.h
>> +++ b/include/linux/irqdesc.h
>> @@ -53,6 +53,9 @@ struct irq_desc {
>> unsigned long last_unhandled; /* Aging timer for unhandled count */
>> unsigned int irqs_unhandled;
>> raw_spinlock_t lock;
>> +#ifdef CONFIG_IRQ_PERCPU_DEVID
>
> Can we just make that a pointer and get rid of the config option ?
Yes. Will add the necessary allocation to irq_set_percpu_devid();
>
>> +#ifdef CONFIG_IRQ_PERCPU_DEVID
>> +void irq_percpu_enable(struct irq_desc *desc)
>> +{
>> + unsigned int cpu = get_cpu();
>
> get_cpu() is overkill here. That's called with desc->lock held and
> interrupts disabled. No way that the cpu can go away :)
Ah, that's only me getting paranoid... ;-)
> I'd rather have a check in the calling function, which makes sure that
> enable_percpu_irq() is called from proper per cpu context. See comment
> below.
>
>> void remove_irq(unsigned int irq, struct irqaction *act)
>> {
>> - __free_irq(irq, act->dev_id);
>> + struct irq_desc *desc = irq_to_desc(irq);
>> +
>> + if (desc && !irq_settings_is_per_cpu_devid(desc))
>
> That probably should be
>
> if (!WARN_ON(....))
Right.
>> + __free_irq(irq, act->dev_id);
>> }
>> EXPORT_SYMBOL_GPL(remove_irq);
>>
>> @@ -1246,7 +1251,7 @@ void free_irq(unsigned int irq, void *dev_id)
>> {
>> struct irq_desc *desc = irq_to_desc(irq);
>>
>> - if (!desc)
>> + if (!desc || irq_settings_is_per_cpu_devid(desc))
>> return;
>
> Please make these percpu_devid checks WARN_ON so we can avoid stupid
> questions on the mailing lists.
OK.
>> #ifdef CONFIG_SMP
>> @@ -1324,7 +1329,8 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
>> if (!desc)
>> return -EINVAL;
>>
>> - if (!irq_settings_can_request(desc))
>> + if (!irq_settings_can_request(desc) ||
>> + irq_settings_is_per_cpu_devid(desc))
>> return -EINVAL;
>
> That's fine.
>
>> if (!handler) {
>> @@ -1409,3 +1415,198 @@ int request_any_context_irq(unsigned int irq, irq_handler_t handler,
>> return !ret ? IRQC_IS_HARDIRQ : ret;
>> }
>> EXPORT_SYMBOL_GPL(request_any_context_irq);
>> +
>> +#ifdef CONFIG_IRQ_PERCPU_DEVID
>> +void enable_percpu_irq(unsigned int irq)
>> +{
>> + unsigned long flags;
>> + struct irq_desc *desc = irq_get_desc_buslock(irq, &flags);
>> +
>> + if (!desc)
>> + return;
>> +
>> + irq_percpu_enable(desc);
>> + irq_put_desc_busunlock(desc, flags);
>
> To make this luser proof and better debuggable I'd like to have that as:
>
> int cpu = smp_processsor_id();
> unsigned long flags;
> ....
> irq_percpu_enable(desc, cpu);
>
> That way we catch at least lusers who call that from random thread
> context - assuming that they enabled some debug options .....
Ah, nice trick.
>> +}
>> +EXPORT_SYMBOL(enable_percpu_irq);
>
> _GPL please if at all. Not sure whether this needs to be available for
> modules.
Well, At the moment, the only potential users of that code are timers,
which cannot be modules. I'd be happy to drop this altogether.
>> +/*
>> + * Internal function to unregister a percpu irqaction.
>> + */
>> +static struct irqaction *__free_percpu_irq(unsigned int irq, void __percpu *dev_id)
>> +{
>> + struct irq_desc *desc = irq_to_desc(irq);
>> + struct irqaction *action;
>> + unsigned long flags;
>> +
>> + WARN(in_interrupt(), "Trying to free IRQ %d from IRQ context!\n", irq);
>> +
>> + if (!desc)
>> + return NULL;
>> +
>> + raw_spin_lock_irqsave(&desc->lock, flags);
>> +
>> + action = desc->action;
>> + if (!action || action->percpu_dev_id != dev_id) {
>> + WARN(1, "Trying to free already-free IRQ %d\n", irq);
>> + raw_spin_unlock_irqrestore(&desc->lock, flags);
>> + return NULL;
>> + }
>> +
>> + /* Found it - now remove it from the list of entries: */
>> + WARN(!cpumask_empty(desc->percpu_enabled),
>> + "percpu IRQ %d still enabled on CPU%d!\n",
>> + irq, cpumask_first(desc->percpu_enabled));
>> + desc->action = NULL;
>> +
>> +#ifdef CONFIG_SMP
>> + /* make sure affinity_hint is cleaned up */
>> + if (WARN_ON_ONCE(desc->affinity_hint))
>> + desc->affinity_hint = NULL;
>> +#endif
>
> We don't want to have an affinity hint for percpu interrupts. That's
> pretty useless AFACIT :)
Copy paste issue. Will fix :)
>> +
>> + raw_spin_unlock_irqrestore(&desc->lock, flags);
>> +
>> + unregister_handler_proc(irq, action);
>> +
>> + /* Make sure it's not being used on another CPU: */
>> + synchronize_irq(irq);
>
> That's not helping w/o making synchronize_irq() aware of the percpu
> stuff. Also there is the question whether we need the ability to
> remove such interrupts in the first place. The target users are low
> level arch interrupts not some random device drivers.
Again, there is no need for this at the moment (the timer code runs
running forever), and this is only there for completeness.
I'll see if I can come up with a synchronize_percpu_irq() without adding
too much bloat to irqdesc.
Thanks for reviewing!
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [RFC PATCH 1/3] genirq: add support for per-cpu dev_id interrupts
From: Thomas Gleixner @ 2011-09-16 9:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E7306C8.4050809@arm.com>
On Fri, 16 Sep 2011, Marc Zyngier wrote:
> Hi Micha?,
>
> On 15/09/11 22:36, Micha? Miros?aw wrote:
> > 2011/9/15 Marc Zyngier <marc.zyngier@arm.com>:
> > [...]
> >> diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
> >> index a103732..f9b7fa3 100644
> >> --- a/include/linux/interrupt.h
> >> +++ b/include/linux/interrupt.h
> >> @@ -95,6 +95,7 @@ typedef irqreturn_t (*irq_handler_t)(int, void *);
> >> * @flags: flags (see IRQF_* above)
> >> * @name: name of the device
> >> * @dev_id: cookie to identify the device
> >> + * @percpu_dev_id: cookie to identify the device
> >> * @next: pointer to the next irqaction for shared interrupts
> >> * @irq: interrupt number
> >> * @dir: pointer to the proc/irq/NN/name entry
> >> @@ -104,17 +105,20 @@ typedef irqreturn_t (*irq_handler_t)(int, void *);
> >> * @thread_mask: bitmask for keeping track of @thread activity
> >> */
> >> struct irqaction {
> > [...]
> >> + void *dev_id;
> >> +#ifdef CONFIG_IRQ_PERCPU_DEVID
> >> + void __percpu *percpu_dev_id;
> >> +#endif
> >
> > Those two can share the memory (in a anonymous union), if I read the
> > idea correctly.
>
> That was the initial implementation, and everything was fine until I
> tried gcc 4.4.1. Having an anonymous union breaks static initialization
> of the structure.
Bah, right. It wants to have brackets around it. So we can use a
separate pointer to get this going and then run coccinelle over it to
fix that up just before 3.2-rc1.
Thanks,
tglx
^ permalink raw reply
* [RFC PATCH 1/3] genirq: add support for per-cpu dev_id interrupts
From: Thomas Gleixner @ 2011-09-16 9:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E7318CB.8010105@arm.com>
On Fri, 16 Sep 2011, Marc Zyngier wrote:
> On 15/09/11 23:49, Thomas Gleixner wrote:
> >> +
> >> + raw_spin_unlock_irqrestore(&desc->lock, flags);
> >> +
> >> + unregister_handler_proc(irq, action);
> >> +
> >> + /* Make sure it's not being used on another CPU: */
> >> + synchronize_irq(irq);
> >
> > That's not helping w/o making synchronize_irq() aware of the percpu
> > stuff. Also there is the question whether we need the ability to
> > remove such interrupts in the first place. The target users are low
> > level arch interrupts not some random device drivers.
>
> Again, there is no need for this at the moment (the timer code runs
> running forever), and this is only there for completeness.
>
> I'll see if I can come up with a synchronize_percpu_irq() without adding
> too much bloat to irqdesc.
You'd need a PROGRESS flag per cpu, which is overkill. What you can do
is to check whether the percpu enabled cpumask is completely empty and
return with a WARN when not.
Thanks,
tglx
^ permalink raw reply
* [PATCH] dmaengine: delete redundant chan_id and chancnt initialization in dma drivers
From: Barry Song @ 2011-09-16 9:43 UTC (permalink / raw)
To: linux-arm-kernel
dma_async_device_register will re-init chan_id and chancnt,
so whatever chan_id and chancnt are set in drivers, they will
be re-written by dma_async_device_register.
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Viresh Kumar <viresh.kumar@st.com>
Cc: Vinod Koul <vinod.koul@intel.com>
Cc: Piotr Ziecik <kosmo@semihalf.com>
Cc: Yong Wang <yong.y.wang@intel.com>
Cc: Jaswinder Singh <jassi.brar@samsung.com>
Cc: Pelagicore AB <info@pelagicore.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
drivers/dma/at_hdmac.c | 5 ++---
drivers/dma/dw_dmac.c | 5 ++---
drivers/dma/intel_mid_dma.c | 2 --
drivers/dma/mpc512x_dma.c | 1 -
drivers/dma/pch_dma.c | 2 --
drivers/dma/pl330.c | 2 --
drivers/dma/timb_dma.c | 3 +--
7 files changed, 5 insertions(+), 15 deletions(-)
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 6a483ea..c1b8c15 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -1260,12 +1260,11 @@ static int __init at_dma_probe(struct platform_device *pdev)
/* initialize channels related values */
INIT_LIST_HEAD(&atdma->dma_common.channels);
- for (i = 0; i < pdata->nr_channels; i++, atdma->dma_common.chancnt++) {
+ for (i = 0; i < pdata->nr_channels; i++) {
struct at_dma_chan *atchan = &atdma->chan[i];
atchan->chan_common.device = &atdma->dma_common;
atchan->chan_common.cookie = atchan->completed_cookie = 1;
- atchan->chan_common.chan_id = i;
list_add_tail(&atchan->chan_common.device_node,
&atdma->dma_common.channels);
@@ -1308,7 +1307,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s), %d channels\n",
dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask) ? "cpy " : "",
dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ? "slave " : "",
- atdma->dma_common.chancnt);
+ pdata->nr_channels);
dma_async_device_register(&atdma->dma_common);
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 4d180ca..9bfd6d3 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -1407,12 +1407,11 @@ static int __init dw_probe(struct platform_device *pdev)
dw->all_chan_mask = (1 << pdata->nr_channels) - 1;
INIT_LIST_HEAD(&dw->dma.channels);
- for (i = 0; i < pdata->nr_channels; i++, dw->dma.chancnt++) {
+ for (i = 0; i < pdata->nr_channels; i++) {
struct dw_dma_chan *dwc = &dw->chan[i];
dwc->chan.device = &dw->dma;
dwc->chan.cookie = dwc->completed = 1;
- dwc->chan.chan_id = i;
if (pdata->chan_allocation_order == CHAN_ALLOCATION_ASCENDING)
list_add_tail(&dwc->chan.device_node,
&dw->dma.channels);
@@ -1468,7 +1467,7 @@ static int __init dw_probe(struct platform_device *pdev)
dma_writel(dw, CFG, DW_CFG_DMA_EN);
printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n",
- dev_name(&pdev->dev), dw->dma.chancnt);
+ dev_name(&pdev->dev), pdata->nr_channels);
dma_async_device_register(&dw->dma);
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c
index 8a3fdd8..cf74a66 100644
--- a/drivers/dma/intel_mid_dma.c
+++ b/drivers/dma/intel_mid_dma.c
@@ -1114,7 +1114,6 @@ static int mid_setup_dma(struct pci_dev *pdev)
midch->chan.device = &dma->common;
midch->chan.cookie = 1;
- midch->chan.chan_id = i;
midch->ch_id = dma->chan_base + i;
pr_debug("MDMA:Init CH %d, ID %d\n", i, midch->ch_id);
@@ -1150,7 +1149,6 @@ static int mid_setup_dma(struct pci_dev *pdev)
dma_cap_set(DMA_SLAVE, dma->common.cap_mask);
dma_cap_set(DMA_PRIVATE, dma->common.cap_mask);
dma->common.dev = &pdev->dev;
- dma->common.chancnt = dma->max_chan;
dma->common.device_alloc_chan_resources =
intel_mid_dma_alloc_chan_resources;
diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c
index b9bae94..8ba4edc 100644
--- a/drivers/dma/mpc512x_dma.c
+++ b/drivers/dma/mpc512x_dma.c
@@ -741,7 +741,6 @@ static int __devinit mpc_dma_probe(struct platform_device *op)
mchan = &mdma->channels[i];
mchan->chan.device = dma;
- mchan->chan.chan_id = i;
mchan->chan.cookie = 1;
mchan->completed_cookie = mchan->chan.cookie;
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c
index 1ac8d4b..5b65362 100644
--- a/drivers/dma/pch_dma.c
+++ b/drivers/dma/pch_dma.c
@@ -926,7 +926,6 @@ static int __devinit pch_dma_probe(struct pci_dev *pdev,
}
pd->dma.dev = &pdev->dev;
- pd->dma.chancnt = nr_channels;
INIT_LIST_HEAD(&pd->dma.channels);
@@ -935,7 +934,6 @@ static int __devinit pch_dma_probe(struct pci_dev *pdev,
pd_chan->chan.device = &pd->dma;
pd_chan->chan.cookie = 1;
- pd_chan->chan.chan_id = i;
pd_chan->membase = ®s->desc[i];
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 00eee59..7f86e7d 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -747,11 +747,9 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
spin_lock_init(&pch->lock);
pch->pl330_chid = NULL;
pch->chan.device = pd;
- pch->chan.chan_id = i;
pch->dmac = pdmac;
/* Add the channel to the DMAC list */
- pd->chancnt++;
list_add_tail(&pch->chan.device_node, &pd->channels);
}
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index f69f90a..6dbdf45 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -753,7 +753,7 @@ static int __devinit td_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&td->dma.channels);
- for (i = 0; i < pdata->nr_channels; i++, td->dma.chancnt++) {
+ for (i = 0; i < pdata->nr_channels; i++) {
struct timb_dma_chan *td_chan = &td->channels[i];
struct timb_dma_platform_data_channel *pchan =
pdata->channels + i;
@@ -767,7 +767,6 @@ static int __devinit td_probe(struct platform_device *pdev)
td_chan->chan.device = &td->dma;
td_chan->chan.cookie = 1;
- td_chan->chan.chan_id = i;
spin_lock_init(&td_chan->lock);
INIT_LIST_HEAD(&td_chan->active_list);
INIT_LIST_HEAD(&td_chan->queue);
--
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
* [RFC PATCH 03/11] DT: regulator: Helper routine to extract regulator_init_data
From: Mark Brown @ 2011-09-16 9:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E72F9A2.20608@ti.com>
On Fri, Sep 16, 2011 at 12:54:18PM +0530, Rajendra Nayak wrote:
> On Friday 16 September 2011 03:42 AM, Grant Likely wrote:
> >However, I can imagine it possible for a regulator to have multiple
> >parents. It may just be better to go with something like the gpio
> >scheme of<phandle gpio-specifier> list of entries. Or maybe just a
> >list of phandles would be sufficient.
> Ok, I can use phandles instead of the name, and have a list to specify
> multiple parents.
> The linux regulator framework though limits to just one parent I guess.
I think if we've got multiple parents they should be listed as named
supplies rather than as parents since it's probably important which is
which. In fact we probably want to list all parents as supplies since
that's what they are, they just have special handling in the code due to
the recursion.
> >These map 1:1 to how Linux currently implements regulators; which
> >isn't exactly bad, but it means that even if Linux changes, we're
> >still have to support this binding. Does this represent the best
> >layout for high level description of regulators?
> I guess, except for some like apply-uV, which like Mark pointed
> out are very linux/runtime policy specific.
> Mark, what do you think?
Yes, overall this feels far too direct.
^ permalink raw reply
* [PATCH v2] dmaengine: add CSR SiRFprimaII DMAC driver
From: Barry Song @ 2011-09-16 9:56 UTC (permalink / raw)
To: linux-arm-kernel
From: Rongjun Ying <rongjun.ying@csr.com>
Cc: Jassi Brar <jaswinder.singh@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Rongjun Ying <rongjun.ying@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
-v2:
use generic xfer API from jassi;
delete sirf self-defined slave config;
fix feedback from vinod;
fix filter function: we have two dmac, clients drivers think the chan id as 0~31;
rename regs to base;
delete redundant chan_id initialization in probe since dmaengine core will
re-write it, refer to my patch too:
[PATCH] dmaengine: delete redundant chan_id and chancnt initialization in dma drivers
http://www.spinics.net/lists/kernel/msg1237455.html
this patch doesn't provide a common way for filter and doesn't use the jassi's v2 patch.
MAINTAINERS | 1 +
drivers/dma/Kconfig | 7 +
drivers/dma/Makefile | 1 +
drivers/dma/sirf-dma.c | 603 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 612 insertions(+), 0 deletions(-)
create mode 100644 drivers/dma/sirf-dma.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 28f65c2..c1237ba 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -739,6 +739,7 @@ M: Barry Song <baohua.song@csr.com>
L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-prima2/
+F: drivers/dma/sirf-dma*
ARM/EBSA110 MACHINE SUPPORT
M: Russell King <linux@arm.linux.org.uk>
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 2e3b3d3..1341bcd 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -187,6 +187,13 @@ config TIMB_DMA
help
Enable support for the Timberdale FPGA DMA engine.
+config SIRF_DMA
+ tristate "CSR SiRFprimaII DMA support"
+ depends on ARCH_PRIMA2
+ select DMA_ENGINE
+ help
+ Enable support for the CSR SiRFprimaII DMA engine.
+
config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
bool
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 30cf3b1..009a222 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_IMX_SDMA) += imx-sdma.o
obj-$(CONFIG_IMX_DMA) += imx-dma.o
obj-$(CONFIG_MXS_DMA) += mxs-dma.o
obj-$(CONFIG_TIMB_DMA) += timb_dma.o
+obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
obj-$(CONFIG_PL330_DMA) += pl330.o
obj-$(CONFIG_PCH_DMA) += pch_dma.o
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
new file mode 100644
index 0000000..90a4660
--- /dev/null
+++ b/drivers/dma/sirf-dma.c
@@ -0,0 +1,603 @@
+/*
+ * DMA controller driver for CSR SiRFprimaII
+ *
+ * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/sirfsoc_dma.h>
+
+#define SIRFSOC_DMA_DESCRIPTORS 16
+#define SIRFSOC_DMA_CHANNELS 16
+
+#define SIRFSOC_DMA_CH_ADDR 0x00
+#define SIRFSOC_DMA_CH_XLEN 0x04
+#define SIRFSOC_DMA_CH_YLEN 0x08
+#define SIRFSOC_DMA_CH_CTRL 0x0C
+
+#define SIRFSOC_DMA_WIDTH_0 0x100
+#define SIRFSOC_DMA_CH_VALID 0x140
+#define SIRFSOC_DMA_CH_INT 0x144
+#define SIRFSOC_DMA_INT_EN 0x148
+#define SIRFSOC_DMA_CH_LOOP_CTRL 0x150
+
+#define SIRFSOC_DMA_MODE_CTRL_BIT 4
+#define SIRFSOC_DMA_DIR_CTRL_BIT 5
+
+struct sirfsoc_dma_desc {
+ struct dma_async_tx_descriptor desc;
+ struct list_head node;
+
+ /* SiRFprimaII 2D-DMA parameters */
+ int xlen; /* DMA xlen */
+ int ylen; /* DMA ylen */
+ int width; /* DMA width */
+};
+
+struct sirfsoc_dma_chan {
+ struct dma_chan chan;
+ struct list_head free;
+ struct list_head prepared;
+ struct list_head queued;
+ struct list_head active;
+ struct list_head completed;
+ dma_cookie_t completed_cookie;
+
+ /* Lock for this structure */
+ spinlock_t lock;
+
+ int direction;
+ int mode;
+ u32 addr;
+};
+
+struct sirfsoc_dma {
+ struct dma_device dma;
+ struct tasklet_struct tasklet;
+ struct sirfsoc_dma_chan channels[SIRFSOC_DMA_CHANNELS];
+ void __iomem *base;
+ int irq;
+};
+
+#define DRV_NAME "sirfsoc_dma"
+
+/* Convert struct dma_chan to struct sirfsoc_dma_chan */
+static inline struct sirfsoc_dma_chan *dma_chan_to_sirfsoc_dma_chan(struct dma_chan *c)
+{
+ return container_of(c, struct sirfsoc_dma_chan, chan);
+}
+
+/* Convert struct dma_chan to struct sirfsoc_dma */
+static inline struct sirfsoc_dma *dma_chan_to_sirfsoc_dma(struct dma_chan *c)
+{
+ struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(c);
+ return container_of(schan, struct sirfsoc_dma, channels[c->chan_id]);
+}
+
+/* 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);
+}
+
+/* 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);
+ }
+
+ /* Schedule tasklet */
+ tasklet_schedule(&sdma->tasklet);
+
+ return IRQ_HANDLED;
+}
+
+/* process completed descriptors */
+static void sirfsoc_dma_process_completed(struct sirfsoc_dma *sdma)
+{
+ dma_cookie_t last_cookie = 0;
+ struct sirfsoc_dma_chan *schan;
+ struct sirfsoc_dma_desc *sdesc;
+ struct dma_async_tx_descriptor *desc;
+ unsigned long flags;
+ LIST_HEAD(list);
+ int i;
+
+ for (i = 0; i < sdma->dma.chancnt; i++) {
+ schan = &sdma->channels[i];
+
+ /* Get all completed descriptors */
+ spin_lock_irqsave(&schan->lock, flags);
+ if (!list_empty(&schan->completed))
+ list_splice_tail_init(&schan->completed, &list);
+ spin_unlock_irqrestore(&schan->lock, flags);
+
+ if (list_empty(&list))
+ continue;
+
+ /* Execute callbacks and run dependencies */
+ list_for_each_entry(sdesc, &list, node) {
+ desc = &sdesc->desc;
+
+ if (desc->callback)
+ desc->callback(desc->callback_param);
+
+ last_cookie = desc->cookie;
+ dma_run_dependencies(desc);
+ }
+
+ /* Free descriptors */
+ spin_lock_irqsave(&schan->lock, flags);
+ list_splice_tail_init(&list, &schan->free);
+ schan->completed_cookie = last_cookie;
+ spin_unlock_irqrestore(&schan->lock, flags);
+ }
+}
+
+/* DMA Tasklet */
+static void sirfsoc_dma_tasklet(unsigned long data)
+{
+ struct sirfsoc_dma *sdma = (void *)data;
+
+ sirfsoc_dma_process_completed(sdma);
+}
+
+/* Submit descriptor to hardware */
+static dma_cookie_t sirfsoc_dma_tx_submit(struct dma_async_tx_descriptor *txd)
+{
+ struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(txd->chan);
+ struct sirfsoc_dma_desc *sdesc;
+ unsigned long flags;
+ dma_cookie_t cookie;
+
+ sdesc = container_of(txd, struct sirfsoc_dma_desc, desc);
+
+ spin_lock_irqsave(&schan->lock, flags);
+
+ /* Move descriptor to queue */
+ list_move_tail(&sdesc->node, &schan->queued);
+
+ /* Update cookie */
+ cookie = schan->chan.cookie + 1;
+ if (cookie <= 0)
+ cookie = 1;
+
+ schan->chan.cookie = cookie;
+ sdesc->desc.cookie = cookie;
+
+ spin_unlock_irqrestore(&schan->lock, flags);
+
+ return cookie;
+}
+
+static int sirfsoc_dma_slave_config(struct sirfsoc_dma_chan *schan,
+ struct dma_slave_config *config)
+{
+ u32 addr, direction;
+ unsigned long flags;
+
+ switch (config->direction) {
+ case DMA_FROM_DEVICE:
+ direction = 0;
+ addr = config->dst_addr;
+ break;
+
+ case DMA_TO_DEVICE:
+ direction = 1;
+ addr = config->src_addr;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ if ((config->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) ||
+ (config->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES))
+ return -EINVAL;
+
+ spin_lock_irqsave(&schan->lock, flags);
+ schan->addr = addr;
+ schan->direction = direction;
+ schan->mode = (config->src_maxburst == 4 ? 1 : 0);
+ spin_unlock_irqrestore(&schan->lock, flags);
+
+ return 0;
+}
+
+static int sirfsoc_dma_terminate_all(struct sirfsoc_dma_chan *schan)
+{
+ struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(&schan->chan);
+ int cid = schan->chan.chan_id;
+ unsigned long flags;
+
+ writel_relaxed(readl_relaxed(sdma->base + SIRFSOC_DMA_INT_EN) & ~(1 << cid),
+ sdma->base + SIRFSOC_DMA_INT_EN);
+ writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_CH_VALID);
+
+ spin_lock_irqsave(&schan->lock, flags);
+ list_splice_tail_init(&schan->active, &schan->free);
+ list_splice_tail_init(&schan->queued, &schan->free);
+ spin_unlock_irqrestore(&schan->lock, flags);
+
+ return 0;
+}
+
+static int sirfsoc_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+ unsigned long arg)
+{
+ struct dma_slave_config *config;
+ struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
+
+ switch (cmd) {
+ case DMA_TERMINATE_ALL:
+ return sirfsoc_dma_terminate_all(schan);
+ case DMA_SLAVE_CONFIG:
+ config = (struct dma_slave_config *)arg;
+ return sirfsoc_dma_slave_config(schan, config);
+
+ default:
+ break;
+ }
+
+ return -ENOSYS;
+}
+
+/* Alloc channel resources */
+static int sirfsoc_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan);
+ struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
+ struct sirfsoc_dma_desc *sdesc;
+ unsigned long flags;
+ LIST_HEAD(descs);
+ int i;
+
+ /* Alloc descriptors for this channel */
+ for (i = 0; i < SIRFSOC_DMA_DESCRIPTORS; i++) {
+ sdesc = kzalloc(sizeof(struct sirfsoc_dma_desc), GFP_KERNEL);
+ if (!sdesc) {
+ dev_notice(sdma->dma.dev, "Memory allocation error. "
+ "Allocated only %u descriptors\n", i);
+ break;
+ }
+
+ dma_async_tx_descriptor_init(&sdesc->desc, chan);
+ sdesc->desc.flags = DMA_CTRL_ACK;
+ sdesc->desc.tx_submit = sirfsoc_dma_tx_submit;
+
+ list_add_tail(&sdesc->node, &descs);
+ }
+
+ /* Return error only if no descriptors were allocated */
+ if (i == 0)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&schan->lock, flags);
+
+ list_splice_tail_init(&descs, &schan->free);
+ spin_unlock_irqrestore(&schan->lock, flags);
+
+ return 0;
+}
+
+/* Free channel resources */
+static void sirfsoc_dma_free_chan_resources(struct dma_chan *chan)
+{
+ struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
+ struct sirfsoc_dma_desc *sdesc, *tmp;
+ unsigned long flags;
+ LIST_HEAD(descs);
+
+ spin_lock_irqsave(&schan->lock, flags);
+
+ /* Channel must be idle */
+ BUG_ON(!list_empty(&schan->prepared));
+ BUG_ON(!list_empty(&schan->queued));
+ BUG_ON(!list_empty(&schan->active));
+ BUG_ON(!list_empty(&schan->completed));
+
+ /* Move data */
+ list_splice_tail_init(&schan->free, &descs);
+
+ spin_unlock_irqrestore(&schan->lock, flags);
+
+ /* Free descriptors */
+ list_for_each_entry_safe(sdesc, tmp, &descs, node)
+ kfree(sdesc);
+}
+
+/* Send pending descriptor to hardware */
+static void sirfsoc_dma_issue_pending(struct dma_chan *chan)
+{
+ struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
+ unsigned long flags;
+
+ spin_lock_irqsave(&schan->lock, flags);
+
+ if (list_empty(&schan->active) && !list_empty(&schan->queued))
+ sirfsoc_dma_execute(schan);
+
+ spin_unlock_irqrestore(&schan->lock, flags);
+}
+
+/* Check request completion status */
+static enum dma_status
+sirfsoc_dma_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
+ struct dma_tx_state *txstate)
+{
+ struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
+ unsigned long flags;
+ dma_cookie_t last_used;
+ dma_cookie_t last_complete;
+
+ spin_lock_irqsave(&schan->lock, flags);
+ last_used = schan->chan.cookie;
+ last_complete = schan->completed_cookie;
+ spin_unlock_irqrestore(&schan->lock, flags);
+
+ dma_set_tx_state(txstate, last_complete, last_used, 0);
+ return dma_async_is_complete(cookie, last_complete, last_used);
+}
+
+static struct dma_async_tx_descriptor *sirfsoc_dma_prep_slave_sg(
+ struct dma_chan *chan, struct scatterlist *sgl,
+ unsigned int sg_len, enum dma_data_direction direction,
+ unsigned long flags)
+{
+ return NULL;
+}
+
+static struct dma_async_tx_descriptor *sirfsoc_dma_prep_genxfer(
+ struct dma_chan *chan, struct xfer_template *xt)
+{
+ struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan);
+ struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
+ struct sirfsoc_dma_desc *sdesc = NULL;
+ unsigned long iflags;
+ int ret;
+
+ /* Get free descriptor */
+ spin_lock_irqsave(&schan->lock, iflags);
+ if (!list_empty(&schan->free)) {
+ sdesc = list_first_entry(&schan->free, struct sirfsoc_dma_desc,
+ node);
+ list_del(&sdesc->node);
+ }
+ spin_unlock_irqrestore(&schan->lock, iflags);
+
+ if (!sdesc) {
+ /* try to free completed descriptors */
+ sirfsoc_dma_process_completed(sdma);
+ ret = 0;
+ goto no_desc;
+ }
+
+ /* Place descriptor in prepared list */
+ spin_lock_irqsave(&schan->lock, iflags);
+ if ((xt->frame_size == 1) && (xt->numf > 0)) {
+ sdesc->xlen = xt->sgl[0].size;
+ sdesc->width = xt->sgl[0].size + xt->sgl[0].icg;
+ sdesc->ylen = xt->numf - 1;
+ list_add_tail(&sdesc->node, &schan->prepared);
+ } else {
+ pr_err("sirfsoc DMA Invalid xfer\n");
+ ret = -EINVAL;
+ goto err_xfer;
+ }
+ spin_unlock_irqrestore(&schan->lock, iflags);
+
+ return &sdesc->desc;
+err_xfer:
+ spin_unlock_irqrestore(&schan->lock, iflags);
+no_desc:
+ return ERR_PTR(ret);
+}
+
+/*
+ * The DMA controller consists of 16 independent DMA channels.
+ * Each channel is allocated to a different function
+ */
+bool sirfsoc_dma_filter_id(struct dma_chan *chan, void *chan_id)
+{
+ unsigned int ch_nr = (unsigned int) chan_id;
+
+ if (ch_nr == chan->chan_id +
+ chan->device->dev_id * SIRFSOC_DMA_CHANNELS)
+ return true;
+
+ return false;
+}
+EXPORT_SYMBOL(sirfsoc_dma_filter_id);
+
+static int __devinit sirfsoc_dma_probe(struct platform_device *op)
+{
+ struct device_node *dn = op->dev.of_node;
+ struct device *dev = &op->dev;
+ struct dma_device *dma;
+ struct sirfsoc_dma *sdma;
+ struct sirfsoc_dma_chan *schan;
+ struct resource res;
+ ulong regs_start, regs_size;
+ u32 id;
+ int retval, i;
+
+ sdma = devm_kzalloc(dev, sizeof(struct sirfsoc_dma), GFP_KERNEL);
+ if (!sdma) {
+ dev_err(dev, "Memory exhausted!\n");
+ return -ENOMEM;
+ }
+
+ if (of_property_read_u32(dn, "cell-index", &id)) {
+ dev_err(dev, "Fail to get DMAC index\n");
+ return -ENODEV;
+ }
+
+ sdma->irq = irq_of_parse_and_map(dn, 0);
+ if (sdma->irq == NO_IRQ) {
+ dev_err(dev, "Error mapping IRQ!\n");
+ return -EINVAL;
+ }
+
+ retval = of_address_to_resource(dn, 0, &res);
+ if (retval) {
+ dev_err(dev, "Error parsing memory region!\n");
+ return retval;
+ }
+
+ regs_start = res.start;
+ regs_size = resource_size(&res);
+
+ if (!devm_request_mem_region(dev, regs_start, regs_size, DRV_NAME)) {
+ dev_err(dev, "Error requesting memory region!\n");
+ return -EBUSY;
+ }
+
+ sdma->base = devm_ioremap(dev, regs_start, regs_size);
+ if (!sdma->base) {
+ dev_err(dev, "Error mapping memory region!\n");
+ return -ENOMEM;
+ }
+
+ retval = devm_request_irq(dev, sdma->irq, &sirfsoc_dma_irq, 0, DRV_NAME,
+ sdma);
+ if (retval) {
+ dev_err(dev, "Error requesting IRQ!\n");
+ return -EINVAL;
+ }
+
+ dma = &sdma->dma;
+ dma->dev = dev;
+ dma->chancnt = SIRFSOC_DMA_CHANNELS;
+
+ dma->device_alloc_chan_resources = sirfsoc_dma_alloc_chan_resources;
+ dma->device_free_chan_resources = sirfsoc_dma_free_chan_resources;
+ dma->device_issue_pending = sirfsoc_dma_issue_pending;
+ dma->device_control = sirfsoc_dma_control;
+ dma->device_tx_status = sirfsoc_dma_tx_status;
+ dma->device_prep_slave_sg = sirfsoc_dma_prep_slave_sg;
+ dma->device_prep_dma_genxfer = sirfsoc_dma_prep_genxfer;
+
+ INIT_LIST_HEAD(&dma->channels);
+ dma_cap_set(DMA_SLAVE, dma->cap_mask);
+ dma_cap_set(DMA_PRIVATE, dma->cap_mask);
+
+ for (i = 0; i < dma->chancnt; i++) {
+ schan = &sdma->channels[i];
+
+ schan->chan.device = dma;
+ schan->chan.cookie = 1;
+ schan->completed_cookie = schan->chan.cookie;
+
+ INIT_LIST_HEAD(&schan->free);
+ INIT_LIST_HEAD(&schan->prepared);
+ INIT_LIST_HEAD(&schan->queued);
+ INIT_LIST_HEAD(&schan->active);
+ INIT_LIST_HEAD(&schan->completed);
+
+ spin_lock_init(&schan->lock);
+ list_add_tail(&schan->chan.device_node, &dma->channels);
+ }
+
+ tasklet_init(&sdma->tasklet, sirfsoc_dma_tasklet, (unsigned long)sdma);
+
+ /* Register DMA engine */
+ dev_set_drvdata(dev, sdma);
+ retval = dma_async_device_register(dma);
+ if (retval) {
+ devm_free_irq(dev, sdma->irq, sdma);
+ irq_dispose_mapping(sdma->irq);
+ }
+
+ return retval;
+}
+
+static int __devexit sirfsoc_dma_remove(struct platform_device *op)
+{
+ struct device *dev = &op->dev;
+ struct sirfsoc_dma *sdma = dev_get_drvdata(dev);
+
+ dma_async_device_unregister(&sdma->dma);
+ devm_free_irq(dev, sdma->irq, sdma);
+ irq_dispose_mapping(sdma->irq);
+
+ return 0;
+}
+
+static struct of_device_id sirfsoc_dma_match[] = {
+ { .compatible = "sirf,prima2-dmac", },
+ {},
+};
+
+static struct platform_driver sirfsoc_dma_driver = {
+ .probe = sirfsoc_dma_probe,
+ .remove = __devexit_p(sirfsoc_dma_remove),
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = sirfsoc_dma_match,
+ },
+};
+
+static int __init sirfsoc_dma_init(void)
+{
+ return platform_driver_register(&sirfsoc_dma_driver);
+}
+module_init(sirfsoc_dma_init);
+
+static void __exit sirfsoc_dma_exit(void)
+{
+ platform_driver_unregister(&sirfsoc_dma_driver);
+}
+module_exit(sirfsoc_dma_exit);
+
+MODULE_AUTHOR("Rongjun Ying <rongjun.ying@csr.com>, "
+ "Barry Song <baohua.song@csr.com>");
+MODULE_DESCRIPTION("SIRFSOC DMA control driver");
+MODULE_LICENSE("GPL");
--
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 0/4] ARM: Samsung: Add board setup for M-5MOLS and NOON010PC30 camera sensors
From: Sylwester Nawrocki @ 2011-09-16 10:27 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
the following patch series adds board setup code for NOOON01PC30 sensor
on GONI and M-5MOLS on UNIVERSAL_C210 board.
Some clocks are modified in line with latest FIMC driver modifcations for v3.2.
Sylwester Nawrocki (4):
ARM: S5PV210: Rename sclk_cam clocks for FIMC media driver
ARM: S5PV210: Add support for NOON010PC30 sensor on GONI board
ARM: EXYNOS4: Rename sclk_cam clocks for FIMC driver
ARM: S5PV210: UNIVERSAL_C210: Add support for M-5MOLS image sensor
arch/arm/mach-exynos4/Kconfig | 3 +
arch/arm/mach-exynos4/clock.c | 6 +-
arch/arm/mach-exynos4/mach-universal_c210.c | 211 ++++++++++++++++++++++++++-
arch/arm/mach-s5pv210/Kconfig | 1 +
arch/arm/mach-s5pv210/clock.c | 6 +-
arch/arm/mach-s5pv210/mach-goni.c | 53 +++++++
6 files changed, 264 insertions(+), 16 deletions(-)
Created against samsung-for-next branch at git://github.com/kgene/linux-samsung.git
on top of the HDMI board patches from Tomasz Stanislawski.
The patches can be pulled from git://git.infradead.org/users/kmpark/linux-2.6-samsung,
branch samsung-board-camera.
Thanks,
--
Sylwester Nawrocki
Samsung Poland R&D Center
^ permalink raw reply
* [PATCH 1/4 (RESEND)] ARM: S5PV210: Rename sclk_cam clocks for FIMC media driver
From: Sylwester Nawrocki @ 2011-09-16 10:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316168873-22257-1-git-send-email-s.nawrocki@samsung.com>
The sclk_cam clocks are now controlled by the top level FIMC media
device driver bound to "s5p-fimc-md" platform device.
Rename sclk_cam clocks so they accessible by the corresponding
driver.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
arch/arm/mach-s5pv210/clock.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index b673f47..231224a4 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -874,8 +874,7 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 },
}, {
.clk = {
- .name = "sclk_cam",
- .devname = "s5pv210-fimc.0",
+ .name = "sclk_cam0",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 3),
},
@@ -884,8 +883,7 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
}, {
.clk = {
- .name = "sclk_cam",
- .devname = "s5pv210-fimc.1",
+ .name = "sclk_cam1",
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 4),
},
--
1.7.6
^ permalink raw reply related
* [PATCH v2 2/4] ARM: S5PV210: Add support for NOON010PC30 sensor on GONI board
From: Sylwester Nawrocki @ 2011-09-16 10:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316168873-22257-1-git-send-email-s.nawrocki@samsung.com>
Add platform data for CIF camera sensor and FIMC platform data
entries for it. Add platform device for s5p-fimc media device
driver and the camera port A I/O pins initialization.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
Kgene, the previous version of this patch should be dropped. I've updated
this version to use generioc signal polarity flags.
Thanks, S.
---
arch/arm/mach-s5pv210/Kconfig | 1 +
arch/arm/mach-s5pv210/mach-goni.c | 53 +++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index ab6a87c..b4c0621 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -100,6 +100,7 @@ config MACH_GONI
select S5PV210_SETUP_I2C2
select S5PV210_SETUP_KEYPAD
select S5PV210_SETUP_SDHCI
+ select S5PV210_SETUP_FIMC
help
Machine support for Samsung GONI board
S5PC110(MCP) is one of package option of S5PV210
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 14578f5..01e4867 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -48,6 +48,11 @@
#include <plat/s5p-time.h>
#include <plat/mfc.h>
#include <plat/regs-fb-v4.h>
+#include <plat/camport.h>
+
+#include <media/v4l2-mediabus.h>
+#include <media/s5p_fimc.h>
+#include <media/noon010pc30.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -272,6 +277,14 @@ static void __init goni_tsp_init(void)
i2c2_devs[0].irq = gpio_to_irq(gpio);
}
+static void goni_camera_init(void)
+{
+ s5pv210_fimc_setup_gpio(S5P_CAMPORT_A);
+
+ /* Set max driver strength on CAM_A_CLKOUT pin. */
+ s5p_gpio_set_drvstr(S5PV210_GPE1(3), S5P_GPIO_DRVSTR_LV4);
+}
+
/* MAX8998 regulators */
#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
@@ -808,6 +821,39 @@ static void goni_setup_sdhci(void)
s3c_sdhci2_set_platdata(&goni_hsmmc2_data);
};
+static struct noon010pc30_platform_data noon010pc30_pldata = {
+ .clk_rate = 16000000UL,
+ .gpio_nreset = S5PV210_GPB(2), /* CAM_CIF_NRST */
+ .gpio_nstby = S5PV210_GPB(0), /* CAM_CIF_NSTBY */
+};
+
+static struct i2c_board_info noon010pc30_board_info = {
+ I2C_BOARD_INFO("NOON010PC30", 0x60 >> 1),
+ .platform_data = &noon010pc30_pldata,
+};
+
+static struct s5p_fimc_isp_info goni_camera_sensors[] = {
+ {
+ .mux_id = 0,
+ .flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
+ V4L2_MBUS_VSYNC_ACTIVE_LOW,
+ .bus_type = FIMC_ITU_601,
+ .board_info = &noon010pc30_board_info,
+ .i2c_bus_num = 0,
+ .clk_frequency = 16000000UL,
+ },
+};
+
+struct s5p_platform_fimc goni_fimc_md_platdata __initdata = {
+ .isp_info = goni_camera_sensors,
+ .num_clients = ARRAY_SIZE(goni_camera_sensors),
+};
+
+struct platform_device s5p_device_fimc_md = {
+ .name = "s5p-fimc-md",
+ .id = -1,
+};
+
static struct platform_device *goni_devices[] __initdata = {
&s3c_device_fb,
&s5p_device_onenand,
@@ -825,6 +871,7 @@ static struct platform_device *goni_devices[] __initdata = {
&s5p_device_fimc0,
&s5p_device_fimc1,
&s5p_device_fimc2,
+ &s5p_device_fimc_md,
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_hsmmc2,
@@ -893,6 +940,12 @@ static void __init goni_machine_init(void)
/* FB */
s3c_fb_set_platdata(&goni_lcd_pdata);
+ /* FIMC */
+ s3c_set_platdata(&goni_fimc_md_platdata, sizeof(goni_fimc_md_platdata),
+ &s5p_device_fimc_md);
+
+ goni_camera_init();
+
/* SPI */
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
--
1.7.6
^ permalink raw reply related
* [PATCH 3/4 (RESEND)] ARM: EXYNOS4: Rename sclk_cam clocks for FIMC driver
From: Sylwester Nawrocki @ 2011-09-16 10:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316168873-22257-1-git-send-email-s.nawrocki@samsung.com>
The sclk_cam clocks are now controlled by the top level FIMC media
device driver bound to "s5p-fimc-md" platform device.
Rename sclk_cam clocks so they accessible by the corresponding
driver.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
arch/arm/mach-exynos4/clock.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
index 53e333b..f0fd0d9 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos4/clock.c
@@ -1025,8 +1025,7 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
}, {
.clk = {
- .name = "sclk_cam",
- .devname = "exynos4-fimc.0",
+ .name = "sclk_cam0",
.enable = exynos4_clksrc_mask_cam_ctrl,
.ctrlbit = (1 << 16),
},
@@ -1035,8 +1034,7 @@ static struct clksrc_clk clksrcs[] = {
.reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
}, {
.clk = {
- .name = "sclk_cam",
- .devname = "exynos4-fimc.1",
+ .name = "sclk_cam1",
.enable = exynos4_clksrc_mask_cam_ctrl,
.ctrlbit = (1 << 20),
},
--
1.7.6
^ permalink raw reply related
* [PATCH 4/4] ARM: S5PV210: UNIVERSAL_C210: Add support for M-5MOLS image sensor
From: Sylwester Nawrocki @ 2011-09-16 10:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316168873-22257-1-git-send-email-s.nawrocki@samsung.com>
Add voltage regulator definitions for M-5MOLS camera, platform data
definition for the sensor and MIPI-CSI receiver drivers.
Add CAM power domain dependencies for FIMC and CSIS devices.
Define required I2C0 bus timings. Setup camera port A GPIO.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
arch/arm/mach-exynos4/Kconfig | 3 +
arch/arm/mach-exynos4/mach-universal_c210.c | 211 ++++++++++++++++++++++++++-
2 files changed, 206 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 7c109e8..4085858 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -178,6 +178,7 @@ config MACH_UNIVERSAL_C210
select S5P_DEV_FIMC1
select S5P_DEV_FIMC2
select S5P_DEV_FIMC3
+ select S5P_DEV_CSIS0
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
@@ -193,6 +194,8 @@ config MACH_UNIVERSAL_C210
select EXYNOS4_SETUP_I2C3
select EXYNOS4_SETUP_I2C5
select EXYNOS4_SETUP_SDHCI
+ select EXYNOS4_SETUP_FIMC
+ select S5P_SETUP_MIPIPHY
help
Machine support for Samsung Mobile Universal S5PC210 Reference
Board.
diff --git a/arch/arm/mach-exynos4/mach-universal_c210.c b/arch/arm/mach-exynos4/mach-universal_c210.c
index e9dbe79..6a27dee 100644
--- a/arch/arm/mach-exynos4/mach-universal_c210.c
+++ b/arch/arm/mach-exynos4/mach-universal_c210.c
@@ -34,9 +34,16 @@
#include <plat/mfc.h>
#include <plat/sdhci.h>
#include <plat/pd.h>
+#include <plat/fimc-core.h>
+#include <plat/camport.h>
+#include <plat/mipi_csis.h>
#include <mach/map.h>
+#include <media/v4l2-mediabus.h>
+#include <media/s5p_fimc.h>
+#include <media/m5mols.h>
+
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define UNIVERSAL_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
@@ -189,6 +196,7 @@ static struct regulator_init_data lp3974_ldo2_data = {
static struct regulator_consumer_supply lp3974_ldo3_consumer[] = {
REGULATOR_SUPPLY("vdd", "exynos4-hdmi"),
REGULATOR_SUPPLY("vdd_pll", "exynos4-hdmi"),
+ REGULATOR_SUPPLY("vdd11", "s5p-mipi-csis.0"),
};
static struct regulator_init_data lp3974_ldo3_data = {
@@ -251,6 +259,10 @@ static struct regulator_init_data lp3974_ldo6_data = {
},
};
+static struct regulator_consumer_supply lp3974_ldo7_consumer[] = {
+ REGULATOR_SUPPLY("vdd18", "s5p-mipi-csis.0"),
+};
+
static struct regulator_init_data lp3974_ldo7_data = {
.constraints = {
.name = "VLCD+VMIPI_1.8V",
@@ -262,6 +274,8 @@ static struct regulator_init_data lp3974_ldo7_data = {
.disabled = 1,
},
},
+ .num_consumer_supplies = ARRAY_SIZE(lp3974_ldo7_consumer),
+ .consumer_supplies = lp3974_ldo7_consumer,
};
static struct regulator_consumer_supply lp3974_ldo8_consumer[] = {
@@ -310,6 +324,9 @@ static struct regulator_init_data lp3974_ldo10_data = {
},
};
+static struct regulator_consumer_supply lp3974_ldo11_consumer =
+ REGULATOR_SUPPLY("dig_28", "0-001f");
+
static struct regulator_init_data lp3974_ldo11_data = {
.constraints = {
.name = "CAM_AF_3.3V",
@@ -321,6 +338,8 @@ static struct regulator_init_data lp3974_ldo11_data = {
.disabled = 1,
},
},
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &lp3974_ldo11_consumer,
};
static struct regulator_init_data lp3974_ldo12_data = {
@@ -349,6 +368,9 @@ static struct regulator_init_data lp3974_ldo13_data = {
},
};
+static struct regulator_consumer_supply lp3974_ldo14_consumer =
+ REGULATOR_SUPPLY("dig_18", "0-001f");
+
static struct regulator_init_data lp3974_ldo14_data = {
.constraints = {
.name = "CAM_I_HOST_1.8V",
@@ -360,8 +382,14 @@ static struct regulator_init_data lp3974_ldo14_data = {
.disabled = 1,
},
},
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &lp3974_ldo14_consumer,
};
+
+static struct regulator_consumer_supply lp3974_ldo15_consumer =
+ REGULATOR_SUPPLY("dig_12", "0-001f");
+
static struct regulator_init_data lp3974_ldo15_data = {
.constraints = {
.name = "CAM_S_DIG+FM33_CORE_1.2V",
@@ -373,6 +401,12 @@ static struct regulator_init_data lp3974_ldo15_data = {
.disabled = 1,
},
},
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &lp3974_ldo15_consumer,
+};
+
+static struct regulator_consumer_supply lp3974_ldo16_consumer[] = {
+ REGULATOR_SUPPLY("a_sensor", "0-001f"),
};
static struct regulator_init_data lp3974_ldo16_data = {
@@ -386,6 +420,8 @@ static struct regulator_init_data lp3974_ldo16_data = {
.disabled = 1,
},
},
+ .num_consumer_supplies = ARRAY_SIZE(lp3974_ldo16_consumer),
+ .consumer_supplies = lp3974_ldo16_consumer,
};
static struct regulator_init_data lp3974_ldo17_data = {
@@ -496,6 +532,15 @@ static struct max8998_platform_data universal_lp3974_pdata = {
.wakeup = true,
};
+
+enum fixed_regulator_id {
+ FIXED_REG_ID_MMC0,
+ FIXED_REG_ID_HDMI_5V,
+ FIXED_REG_ID_CAM_S_IF,
+ FIXED_REG_ID_CAM_I_CORE,
+ FIXED_REG_ID_CAM_VT_DIO,
+};
+
static struct regulator_consumer_supply hdmi_fixed_consumer =
REGULATOR_SUPPLY("hdmi-en", "exynos4-hdmi");
@@ -518,7 +563,7 @@ static struct fixed_voltage_config hdmi_fixed_voltage_config = {
static struct platform_device hdmi_fixed_voltage = {
.name = "reg-fixed-voltage",
- .id = 6,
+ .id = FIXED_REG_ID_HDMI_5V,
.dev = {
.platform_data = &hdmi_fixed_voltage_config,
},
@@ -625,6 +670,12 @@ static void __init universal_touchkey_init(void)
gpio_direction_output(gpio, 1);
}
+
+static struct s3c2410_platform_i2c universal_i2c0_platdata __initdata = {
+ .frequency = 350 * 1000,
+ .sda_delay = 200,
+};
+
/* GPIO KEYS */
static struct gpio_keys_button universal_gpio_keys_tables[] = {
{
@@ -710,7 +761,7 @@ static struct fixed_voltage_config mmc0_fixed_voltage_config = {
static struct platform_device mmc0_fixed_voltage = {
.name = "reg-fixed-voltage",
- .id = 0,
+ .id = FIXED_REG_ID_MMC0,
.dev = {
.platform_data = &mmc0_fixed_voltage_config,
},
@@ -744,18 +795,149 @@ static void __init universal_sdhci_init(void)
s3c_sdhci3_set_platdata(&universal_hsmmc3_data);
}
-/* I2C0 */
-static struct i2c_board_info i2c0_devs[] __initdata = {
- /* Camera, To be updated */
-};
-
/* I2C1 */
static struct i2c_board_info i2c1_devs[] __initdata = {
/* Gyro, To be updated */
};
+static struct regulator_consumer_supply cam_i_core_supply =
+ REGULATOR_SUPPLY("core", "0-001f");
+
+static struct regulator_init_data cam_i_core_reg_init_data = {
+ .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cam_i_core_supply,
+};
+
+static struct fixed_voltage_config cam_i_core_fixed_voltage_cfg = {
+ .supply_name = "CAM_I_CORE_1.2V",
+ .microvolts = 1200000,
+ .gpio = EXYNOS4_GPE2(2), /* CAM_8M_CORE_EN */
+ .enable_high = 1,
+ .init_data = &cam_i_core_reg_init_data,
+};
+
+static struct platform_device cam_i_core_fixed_reg_dev = {
+ .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_I_CORE,
+ .dev = { .platform_data = &cam_i_core_fixed_voltage_cfg },
+};
+
+static struct regulator_consumer_supply cam_s_if_supply =
+ REGULATOR_SUPPLY("d_sensor", "0-001f");
+
+static struct regulator_init_data cam_s_if_reg_init_data = {
+ .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cam_s_if_supply,
+};
+
+static struct fixed_voltage_config cam_s_if_fixed_voltage_cfg = {
+ .supply_name = "CAM_S_IF_1.8V",
+ .microvolts = 1800000,
+ .gpio = EXYNOS4_GPE3(0), /* CAM_PWR_EN1 */
+ .enable_high = 1,
+ .init_data = &cam_s_if_reg_init_data,
+};
+
+static struct platform_device cam_s_if_fixed_reg_dev = {
+ .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_S_IF,
+ .dev = { .platform_data = &cam_s_if_fixed_voltage_cfg },
+};
+
+static struct s5p_platform_mipi_csis mipi_csis_platdata = {
+ .clk_rate = 166000000UL,
+ .lanes = 2,
+ .alignment = 32,
+ .hs_settle = 12,
+ .phy_enable = s5p_csis_phy_enable,
+};
+
+static int m5mols_set_power(struct device *dev, int on)
+{
+ gpio_set_value(EXYNOS4_GPE4(4), !on); /* CAM_LEVEL_EN1 */
+ gpio_set_value(EXYNOS4_GPE4(5), !!on); /* CAM_LEVEL_EN2 */
+ return 0;
+}
+
+static struct m5mols_platform_data m5mols_platdata = {
+ .gpio_reset = EXYNOS4_GPE2(5), /* CAM_MEGA_nRST */
+ .reset_polarity = 0,
+ .irq = IRQ_EINT(13),
+ .set_power = m5mols_set_power,
+};
+
+static struct i2c_board_info m5mols_board_info = {
+ I2C_BOARD_INFO("M5MOLS", 0x1F),
+ .platform_data = &m5mols_platdata,
+ .irq = IRQ_EINT(13),
+};
+
+static struct s5p_fimc_isp_info universal_camera_sensors[] = {
+ {
+ .mux_id = 0,
+ .flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
+ V4L2_MBUS_VSYNC_ACTIVE_LOW,
+ .bus_type = FIMC_MIPI_CSI2,
+ .board_info = &m5mols_board_info,
+ .i2c_bus_num = 0,
+ .clk_frequency = 21600000UL,
+ .csi_data_align = 32,
+ },
+};
+
+static struct s5p_platform_fimc fimc_md_platdata = {
+ .isp_info = universal_camera_sensors,
+ .num_clients = ARRAY_SIZE(universal_camera_sensors),
+};
+
+struct platform_device s5p_device_fimc_md = {
+ .name = "s5p-fimc-md",
+ .id = -1,
+};
+
+static void universal_camera_init(void)
+{
+ int gpio;
+
+ s3c_set_platdata(&mipi_csis_platdata, sizeof(mipi_csis_platdata),
+ &s5p_device_mipi_csis0);
+ s3c_set_platdata(&fimc_md_platdata, sizeof(fimc_md_platdata),
+ &s5p_device_fimc_md);
+ exynos4_fimc_setup_gpio(S5P_CAMPORT_A);
+ /*
+ * Configure the I2C level shifter inhibit pins. These are
+ * controlled through the sensor driver set_power callbacks.
+ */
+ gpio = EXYNOS4_GPE4(4);
+ gpio_request(gpio, "CAM_LVL_EN1");
+ gpio_direction_output(gpio, 1);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ gpio_free(gpio);
+
+ gpio = EXYNOS4_GPE4(5);
+ gpio_request(gpio, "CAM_LVL_EN2");
+ gpio_direction_output(gpio, 0);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_DOWN);
+ gpio_free(gpio);
+
+ /* Initialize GPIOs controlled directly by the sensor drivers. */
+ gpio = EXYNOS4_GPE2(5), /* CAM_MEGA_nRST */
+ gpio_request(gpio, "CAM_8M_NRST");
+ gpio_direction_output(gpio, 0);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_DOWN);
+ gpio_free(gpio);
+
+ gpio = EXYNOS4_GPX1(5);
+ gpio_request(gpio, "8M_ISP_INT");
+ s5p_register_gpio_interrupt(gpio);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ gpio_free(gpio);
+
+}
+
static struct platform_device *universal_devices[] __initdata = {
/* Samsung Platform Devices */
+ &s5p_device_mipi_csis0,
&s5p_device_fimc0,
&s5p_device_fimc1,
&s5p_device_fimc2,
@@ -764,6 +946,7 @@ static struct platform_device *universal_devices[] __initdata = {
&s3c_device_hsmmc0,
&s3c_device_hsmmc2,
&s3c_device_hsmmc3,
+ &s3c_device_i2c0,
&s3c_device_i2c3,
&s3c_device_i2c5,
&s5p_device_i2c_hdmiphy,
@@ -781,6 +964,9 @@ static struct platform_device *universal_devices[] __initdata = {
&s5p_device_mfc_l,
&s5p_device_mfc_r,
&exynos4_device_pd[PD_MFC],
+ &exynos4_device_pd[PD_CAM],
+ &cam_i_core_fixed_reg_dev,
+ &cam_s_if_fixed_reg_dev,
};
static void __init universal_map_io(void)
@@ -814,7 +1000,7 @@ static void __init universal_machine_init(void)
universal_sdhci_init();
s5p_tv_setup();
- i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
+ s3c_i2c0_set_platdata(&universal_i2c0_platdata);
i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
universal_tsp_init();
@@ -829,9 +1015,18 @@ static void __init universal_machine_init(void)
i2c_register_board_info(I2C_GPIO_BUS_12, i2c_gpio12_devs,
ARRAY_SIZE(i2c_gpio12_devs));
+ universal_camera_init();
+
/* Last */
platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
+
s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
+
+ s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
+ s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
}
MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
--
1.7.6
^ permalink raw reply related
* READ THIS: the next mach-types update
From: Richard Cochran @ 2011-09-16 10:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110915102528.GI6267@n2100.arm.linux.org.uk>
On Thu, Sep 15, 2011 at 11:25:28AM +0100, Russell King - ARM Linux wrote:
> -devixp MACH_DEVIXP DEVIXP 2885
> -miccpt MACH_MICCPT MICCPT 2886
> -mic256 MACH_MIC256 MIC256 2887
Russell,
I had posted support for these some time ago, and shortly thereafter
the whole "clean up the ARM mess" campaign started. I did not follow
up on posting a second time, for fear of adding more churn.
So, my question is, what can I do to keep these in the list?
Can I get plain old board setup files merged (like three of the
following) ...
arch/arm/mach-ixp4xx/Kconfig | 8 +
arch/arm/mach-ixp4xx/Makefile | 2 +
arch/arm/mach-ixp4xx/include/mach/uncompress.h | 2 +-
arch/arm/mach-ixp4xx/miccpt-pci.c | 78 +++++++++
arch/arm/mach-ixp4xx/miccpt-setup.c | 219 ++++++++++++++++++++++++
5 files changed, 308 insertions(+), 1 deletions(-)
or would I have to somehow upgrade to DT?
Thanks,
Richard
^ permalink raw reply
* try_to_freeze() called with IRQs disabled on ARM
From: Martin Schwidefsky @ 2011-09-16 10:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110902174812.GD6619@n2100.arm.linux.org.uk>
Hi Russell,
Russell King - ARM Linux <linux@arm.linux.org.uk> wrote on 09/02/2011
07:48:12 PM:
> On Fri, Sep 02, 2011 at 07:40:34PM +0200, Ulrich Weigand wrote:
> > Russell King - ARM Linux <linux@arm.linux.org.uk> wrote on 09/02/2011
> > 07:22:59 PM:
> > > On Fri, Sep 02, 2011 at 04:47:35PM +0200, Ulrich Weigand wrote:
> > > > Assume the scenario you initally describe, where a first signal is
> > > > ignored and leads to system call restart. With your latest patch,
> > > > you call into syscall_restart which sets everything up to restart
> > > > the call (with interrupts disabled).
> > >
> > > I don't think SIG_IGN signals even set the TIF work flag, so they
> > > never even cause a call into do_signal(). Therefore, as far as
> > > syscalls go, attempting to send a process (eg) a SIGINT which its
> > > handler is set to SIG_IGN results in the process not even being
> > > notified about the attempt - we won't even wake up while the
> > > syscall is sleeping.
> >
> > I don't see why SIG_IGN signals shouldn't set the TIF work flag;
> > the decision whether to ignore a signal is only made once we've
> > got to get_signal_to_deliver.
>
> Yes, having looked deeper, you seem to be right - but only if the thread
> is being ptraced. If it's not being ptraced, ignored signals don't
> make it that far.
>
> And yes, we can end up processing the interrupt before the SVC is
> executed, which is still a hole. So we need to avoid doing the
> restart in userspace - which might actually make things easier.
> I'll take a look into that over the weekend.
After some more discussions with Uli I've now created a patch that
hopefully will address the issue on s390. The new code always uses
the TIF_RESTART_SVC work flag to restart the system call if there
is no signal to deliver. Only if there is a signal to deliver the
traditional rewind of the instruction pointer is used to restart
the system call (for -ERESTARTNOINTR and -ERESTARTSYS with a
SA_RESTART signal handler).
In case you are interested in the code is available at
git://git390.marist.edu/pub/scm/linux-2.6.git features
in particular git commit 4a6a001c39ac196530d8378408b61d6d2fee70d9.
blue skies,
Martin
^ permalink raw reply
* [PATCH 16/19] ARM: move iotable mappings within the vmalloc region
From: Jamie Iles @ 2011-09-16 10:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1316156850-31013-17-git-send-email-nico@fluxnic.net>
Hi Nicolas,
On Fri, Sep 16, 2011 at 03:07:27AM -0400, Nicolas Pitre wrote:
> From: Nicolas Pitre <nicolas.pitre@linaro.org>
>
> In order to remove the build time variation between different SOCs with
> regards to VMALLOC_END, the iotable mappings are now allocated inside
> the vmalloc region. This allows for VMALLOC_END to be identical across
> all machines.
>
> Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
> ---
> arch/arm/include/asm/pgtable.h | 8 +------
> arch/arm/mm/mmu.c | 42 +++++++++++++++++++++++++++++----------
> 2 files changed, 32 insertions(+), 18 deletions(-)
>
> diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
> index 5750704e02..950dee3ce2 100644
> --- a/arch/arm/include/asm/pgtable.h
> +++ b/arch/arm/include/asm/pgtable.h
> @@ -21,7 +21,6 @@
> #else
>
> #include <asm/memory.h>
> -#include <mach/vmalloc.h>
> #include <asm/pgtable-hwdef.h>
>
> /*
> @@ -31,15 +30,10 @@
> * any out-of-bounds memory accesses will hopefully be caught.
> * The vmalloc() routines leaves a hole of 4kB between each vmalloced
> * area for the same reason. ;)
> - *
> - * Note that platforms may override VMALLOC_START, but they must provide
> - * VMALLOC_END. VMALLOC_END defines the (exclusive) limit of this space,
> - * which may not overlap IO space.
> */
> -#ifndef VMALLOC_START
> #define VMALLOC_OFFSET (8*1024*1024)
> #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
> -#endif
> +#define VMALLOC_END 0xff000000UL
Only a minor nit, but I think this requires an update to
Documentation/arm/memory.txt as this says that VMALLOC_END -> feffffff
is free for platform use but this won't ever be true now.
Jamie
^ permalink raw reply
* [PATCH 1/3] ARM: debug: use kconfig choice for selecting DEBUG_LL UART
From: Will Deacon @ 2011-09-16 11:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E723723.2030609@codeaurora.org>
Hi Stephen,
On Thu, Sep 15, 2011 at 06:34:27PM +0100, Stephen Boyd wrote:
> On 08/16/11 14:41, Will Deacon wrote:
> > +choice
> > + prompt "Kernel low-level debugging port"
> > + depends on DEBUG_LL
> > +
> > + config DEBUG_DC21285_PORT
> > + bool "Kernel low-level debugging messages via footbridge serial port"
> > + depends on FOOTBRIDGE
> > + help
> > + Say Y here if you want the debug print routines to direct
> > + their output to the serial port in the DC21285 (Footbridge).
> > + Saying N will cause the debug messages to appear on the first
> > + 16550 serial port.
> > +
> > + config DEBUG_CLPS711X_UART2
> > + bool "Kernel low-level debugging messages via UART2"
> > + depends on ARCH_CLPS711X
> > + help
> > + Say Y here if you want the debug print routines to direct
> > + their output to the second serial port on these devices.
> > + Saying N will cause the debug messages to appear on the first
> > + serial port.
>
> How would I unselect this UART2 config to get serial output on UART1? As
> far as I can tell there isn't an option for NONE in a choice menu.
Ah yes. This will need to be added as part of the platform updates to go via
Arnd. It should be easy enough just to have a DEBUG_CLPS711X_UART1 option,
for example, and the platform code will fall back to the first UART.
Will
^ permalink raw reply
* [GIT PULL] Perf, PMU and hw_breakpoint updates for 3.2
From: Will Deacon @ 2011-09-16 11:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110901210614.GA5209@e102144-lin.cambridge.arm.com>
Hi Russell,
On Thu, Sep 01, 2011 at 10:06:14PM +0100, Will Deacon wrote:
> Please pull these perf/pmu/hw_breakpoint updates for 3.2. Note that the
> patch entitled "perf: provide PMU when initing events" is a cherry-pick
> from tip/master.
>
> I would have waited until -rc5 to send this, but I'm on holiday without
> internet for the next couple of weeks. Instead this is taken against
> the recent merge commit of your fixes branch by Linus.
[...]
> The following changes since commit 90e93648c41bd29a72f6ec55ce27a23c209eab8c:
>
> Merge branch 'fixes' of master.kernel.org:/home/rmk/linux-2.6-arm (2011-08-29 16:34:07 -0700)
>
> are available in the git repository at:
>
> git://linux-arm.org/linux-2.6-wd.git for-rmk
I can't see these in your for-next branch, so would you like me to rebase
onto -rc6 now that it's around or are you happy to take this as-is?
Cheers,
Will
^ permalink raw reply
* [GIT PULL] Samsung Fixes for v3.1-rc7
From: Kukjin Kim @ 2011-09-16 11:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201109151732.59886.arnd@arndb.de>
Arnd Bergmann wrote:
>
> On Thursday 15 September 2011, Kukjin Kim wrote:
> > This is Samsung fixes for v3.1
> >
> > Please pull from:
> > git://github.com/kgene/linux-samsung.git samsung-fixes-2
> > As you know, git.kernel.org/master.kernel.org has been down so I use
> > temporary git repo. at github now.
> >
> > These things are needed for v3.1 and if any problems, please let me
know.
> >
> > As a note, others for v3.2 will be sent in the next week...
>
> Thanks, pulled.
>
> Is it correct that you want none of these patches to be backported
> into the stable or longterm releases? Some of these look like they
> should be marked 'Cc: stable at kernel.org'.
>
(Cc'ed Greg K-H)
Yes, you're right. Some patches are needed to sent to stable at kernel.org.
But unfortunately, when they have been submitted, there was no 'Cc:
stable at kernel.org'...
In this case, I'm not sure which following method is proper...
- to send 'pull request' to Greg / stable at kernel.org like bug fix during -rc
- to submit each patches with adding 'Cc: stable at kernel.org' again
- or ?
Please kindly let me know.
Thanks, have a nice weekend.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply
* [PATCH v2 5/6] OMAP: omap_device: Create a default omap_device_pm_latency
From: Cousson, Benoit @ 2011-09-16 11:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1314973520-3585-6-git-send-email-b-cousson@ti.com>
Hi Kevin,
On 9/2/2011 4:25 PM, Cousson, Benoit wrote:
> Most devices are using the same default omap_device_pm_latency structure
> during device built. In order to avoid the duplication of the same
> structure everywhere, add a default structure that will be used if
> the device does not have an explicit one.
[...]
> - od->pm_lats = pm_lats;
> - od->pm_lats_cnt = pm_lats_cnt;
> + if (pm_lats) {
> + od->pm_lats = pm_lats;
> + od->pm_lats_cnt = pm_lats_cnt;
> + } else {
> + od->pm_lats = omap_default_latency;
> + od->pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
> + }
Here is the fix for that part. I did the easy version :-). Splitting the structure in two parts will indeed require more work.
I updated the for_3.2/1_omap_device_cleanup branch.
Regards,
Benoit
---
^ 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