* [PATCH 0/4 V3] irqchip: gic: Introduce ARM GICv2m MSI(-X) support
From: Mark Rutland @ 2014-07-18 9:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140717141235.GR13108@titan.lakedaemon.net>
On Thu, Jul 17, 2014 at 03:12:35PM +0100, Jason Cooper wrote:
> On Thu, Jul 17, 2014 at 02:55:34PM +0100, Mark Rutland wrote:
> > Hi Jason,
> >
> > On Thu, Jul 17, 2014 at 02:18:54PM +0100, Jason Cooper wrote:
> > > On Wed, Jul 09, 2014 at 06:05:00PM -0500, suravee.suthikulpanit at amd.com wrote:
> > > > From: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
> > > >
> > > > This patch set introduces support for MSI(-X) in GICv2m specification,
> > > > which is implemented in some variation of GIC400.
> > > >
> > > > This depends on and has been tested with the V7 of"Add support for PCI in AArch64"
> > > > (https://lkml.org/lkml/2014/3/14/320).
> > > >
> > > > Changes in V3:
> > > > * Rebase to git://git.infradead.org/users/jcooper/linux.git irqchip/gic
> > > > (per Jason Cooper request)
> > > > * Misc fix/clean up per Mark Rutland comments
> > > > * Minor Clean up in the driver/irqchip/irq-gic-v2m.c: alloc_msi_irqs()
> > > > * Patch 4 is new to the series:
> > > > * Add ARM64-specific version arch_setup_msi_irqs() to allow support
> > > > for Multiple MSI.
> > > > * Add support for Multiple MSI for GICv2m.
> > > >
> > > > Suravee Suthikulpanit (4):
> > > > irqchip: gic: Add binding probe for ARM GIC400
> > > > irqchip: gic: Restructuring ARM GIC code
> > > > irqchip: gic: Add supports for ARM GICv2m MSI(-X)
> > > > irqchip: gicv2m: Add support for multiple MSI for ARM64 GICv2m
> > >
> > > Ok, patch #1 applied to irqchip/urgent. Patches 2 and 3 applied to
> > > irqchip/gic with irqchip/urgent merged in. To facilitate
> > > testing/merging, I've prepared an unsigned tag for you on the
> > > irqchip/gic branch:
> >
> > I'm a little concerned that this is all going through for v3.17 without
> > a {Reviewed,Acked}-by from Marc or anyone working with GIC{,v2m}.
>
> Well, that's why it's not in irqchip/core yet. ;-) It can be undone if
> needed.
Ah, perhaps I was a litte premature. :)
> > While his comments on v1 have been addressed, he has not had a chance to
> > acknowledge the solutions. I appreciate Marc's holiday is unfortunately
> > timed.
> >
> > I also have an open concern with the binding with regard to the
> > orthogonality of GICV GICH and the MSI registers.
> >
> > Suravee, do you need this urgently for v3.17? I was under the impression
> > that we wouldn't have full PCIe support by then.
>
> If Suravee is ok with it, I can drop them for now and he can resend for
> v3.18. Since we've worked out a way to merge it all in one window, I
> don't think it would hurt anything to wait.
Ok.
> I'll leave these in irqchip/for-next until I hear from Suravee, then
> I'll drop the lot till we hear from Marc and look at the timing.
Keeping it in for-next for testing sounds like a good idea, but until we
hear from Marc I wouldn't want to see this queued for mainline. So the
above sounds fine to me.
Cheers,
Mark.
^ permalink raw reply
* ASoC: samsung: MACH_SMDKC100
From: Paul Bolle @ 2014-07-18 8:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1404288063.12021.13.camel@x220>
Kukjin,
On Wed, 2014-07-02 at 10:01 +0200, Paul Bolle wrote:
> Your commit 52ad6582ceb2 ("ARM: S5PC100: no more support S5PC100 SoC"
> landed in next-20140702. It removed the Kconfig symbol MACH_SMDKC100
> (and a lot of other stuff).
>
> Is the trivial patch to also remove the last two references to
> MACH_SMDKC100 from sound/soc/samsung/Kconfig/ queued somewhere? I don't
> think it was part of the series that included the above commit.
Have you had time to look at this? Those last two references to
MACH_SMDKC100 can still be seen in next-20140718.
Paul Bolle
^ permalink raw reply
* [PATCH v13 6/8] arm: add pmd_[dirty|mkclean] for THP
From: Will Deacon @ 2014-07-18 8:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1405666386-15095-7-git-send-email-minchan@kernel.org>
On Fri, Jul 18, 2014 at 07:53:04AM +0100, Minchan Kim wrote:
> MADV_FREE needs pmd_dirty and pmd_mkclean for detecting recent
> overwrite of the contents since MADV_FREE syscall is called for
> THP page.
>
> This patch adds pmd_dirty and pmd_mkclean for THP page MADV_FREE
> support.
>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Steve Capper <steve.capper@linaro.org>
> Cc: Russell King <linux@arm.linux.org.uk>
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Minchan Kim <minchan@kernel.org>
> ---
> arch/arm/include/asm/pgtable-3level.h | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
> index 85c60adc8b60..830f84f2d277 100644
> --- a/arch/arm/include/asm/pgtable-3level.h
> +++ b/arch/arm/include/asm/pgtable-3level.h
> @@ -220,6 +220,8 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
> #define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
> #endif
>
> +#define pmd_dirty(pmd) (pmd_val(pmd) & PMD_SECT_DIRTY)
> +
> #define PMD_BIT_FUNC(fn,op) \
> static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; }
>
> @@ -228,6 +230,7 @@ PMD_BIT_FUNC(mkold, &= ~PMD_SECT_AF);
> PMD_BIT_FUNC(mksplitting, |= PMD_SECT_SPLITTING);
> PMD_BIT_FUNC(mkwrite, &= ~PMD_SECT_RDONLY);
> PMD_BIT_FUNC(mkdirty, |= PMD_SECT_DIRTY);
> +PMD_BIT_FUNC(mkclean, &= ~PMD_SECT_DIRTY);
> PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
>
> #define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
Looks fine to me, but again, it would be great if Steve can take a look too.
Will
^ permalink raw reply
* [PATCH v5 7/8] drivers: cpuidle: initialize Exynos driver through DT
From: Chander Kashyap @ 2014-07-18 8:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140717142019.GA21732@e102568-lin.cambridge.arm.com>
Hi Lorenzo,
On 17 July 2014 19:50, Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote:
> On Wed, Jun 25, 2014 at 04:23:38PM +0100, Bartlomiej Zolnierkiewicz wrote:
>>
>> Hi,
>>
>> On Wednesday, June 25, 2014 03:10:20 PM Lorenzo Pieralisi wrote:
>> > With the introduction of DT based idle states, CPUidle drivers for
>> > ARM can now initialize idle states data through properties in the device
>> > tree.
>> >
>> > This patch adds code to the Exynos CPUidle driver to dynamically
>> > initialize idle states data through the updated device tree source
>> > files.
>> >
>> > Cc: Kukjin Kim <kgene.kim@samsung.com>
>> > Cc: Tomasz Figa <t.figa@samsung.com>
>> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> > ---
>> > Compile tested, I am not sure I patched the right dts files, please check.
>>
>> cpuidle-exynos driver is currently working properly in deeper cpuidle
>> mode (AFTR) on Exynos4210 and Exynos5250 (please also see the following
>> patch from Tomasz Figa: [1]). There is ongoing work to AFTR mode work
>> also on Exynos4x12 and Exynos3250 but it is not complete yet. Exynos5410
>> OTOH should probably use the generic big little cpuidle driver (this SoC
>> is similar to Exynos5420 one for which Chander Kashyap has developed
>> cpuidle-big_little support [2]).
>>
>> Making long story short, I think that your patch should depend on patch
>> [1] and update only exynos4210.dtsi and exynos5250.dtsi. Also for your
>> patch #6 there needs to be some coordination with merging of Chander's
>> patchset ([2]).
>>
>> [1] http://www.spinics.net/lists/arm-kernel/msg341023.html
>> [2] https://www.mail-archive.com/linux-kernel at vger.kernel.org/msg664470.html
>
>
> exynos4210.dtsi does not even have cpu nodes in it. Should I add them or
> this might trigger regression (ie cpu_logical_map()) ?
Yes that can cause regression.
>
> I will post a new version soon, should I just patch 5250 for now ?
>
> I would need help to test this patch thanks.
I can test the patch for 5250.
>
> Lorenzo
>
>> > .../devicetree/bindings/arm/exynos/idle-states.txt | 27 ++++++++++++++++++++
>> > arch/arm/boot/dts/exynos3250.dtsi | 16 ++++++++++++
>> > arch/arm/boot/dts/exynos5250.dtsi | 15 +++++++++++
>> > arch/arm/boot/dts/exynos5410.dtsi | 17 +++++++++++++
>> > drivers/cpuidle/Kconfig.arm | 1 +
>> > drivers/cpuidle/cpuidle-exynos.c | 29 +++++++++++++---------
>> > 6 files changed, 93 insertions(+), 12 deletions(-)
>> > create mode 100644 Documentation/devicetree/bindings/arm/exynos/idle-states.txt
>>
>> Best regards,
>> --
>> Bartlomiej Zolnierkiewicz
>> Samsung R&D Institute Poland
>> Samsung Electronics
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-pm" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>>
>
--
with warm regards,
Chander Kashyap
^ permalink raw reply
* [PATCH RFCv3 08/14] arm64: introduce aarch64_insn_gen_movewide()
From: Will Deacon @ 2014-07-18 8:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CABg9mcv4t_BwcaM0qgLivDBDGEfH0FwfTAR2QjJc4+i=M58cng@mail.gmail.com>
On Fri, Jul 18, 2014 at 06:47:22AM +0100, Z Lim wrote:
> (resending this email in case the first one got caught in your spam
> filter. sorry.)
>
> On Thu, Jul 17, 2014 at 10:41:02AM +0100, Will Deacon wrote:
> > On Wed, Jul 16, 2014 at 11:04:22PM +0100, Zi Shen Lim wrote:
> > > On Wed, Jul 16, 2014 at 05:17:15PM +0100, Will Deacon wrote:
> > > > On Tue, Jul 15, 2014 at 07:25:06AM +0100, Zi Shen Lim wrote:
> > > > > Introduce function to generate move wide (immediate) instructions.
> [...]
> > > > > + switch (variant) {
> > > > > + case AARCH64_INSN_VARIANT_32BIT:
> > > > > + BUG_ON(shift != 0 && shift != 16);
> > > > > + break;
> > > > > + case AARCH64_INSN_VARIANT_64BIT:
> > > > > + insn |= BIT(31);
> > > > > + BUG_ON(shift != 0 && shift != 16 && shift != 32 &&
> > > > > + shift != 48);
> > > >
> > > > Would be neater as a nested switch, perhaps? If you reorder the
> > > > outer-switch, you could probably fall-through too and combine the shift
> > > > checks.
> > >
> > > Not sure I picture what you had in mind... I couldn't come up with a
> > > neater version with the properties you described.
> > >
> > > The alternative I had was using masks instead of integer values, but
> > > one could argue that while neater, it could also be harder to read:
> > >
> > > switch (variant) {
> > > case AARCH64_INSN_VARIANT_32BIT:
> > > BUG_ON(shift & ~BIT(4));
> > > break;
> > > case AARCH64_INSN_VARIANT_64BIT:
> > > insn |= BIT(31);
> > > BUG_ON(shift & ~GENMASK(5, 4));
> > > ...
> >
> > I was thinking of using nested switches, but that doesn't fall out like I
> > hoped. How about:
> >
> > switch (variant) {
> > case AARCH64_INSN_VARIANT_64BIT:
> > BUG_ON(shift != 32 && shift != 48);
>
> Sorry this won't work. For example, on the valid case of shift==0,
> we'll barf right here - no fallthrough.
>
> Shall we just leave the code as is? :)
Yeah, I'm an idiot ;)
Cheers,
Will
^ permalink raw reply
* HYP panic with 3.16-rc5, arm64 + 64k pages
From: Will Deacon @ 2014-07-18 8:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <53C8086E.5060903@amd.com>
Hi Joel, Don,
On Thu, Jul 17, 2014 at 06:31:26PM +0100, Joel Schopp wrote:
>
> On 07/17/2014 10:28 AM, Will Deacon wrote:
> > Initializing cgroup subsys cpu
> > Linux version 3.16.0-rc5 (will at edgewater-inn) (gcc version 4.9.0 20140214 (experimental) (aarch64-trunk.530) ) #1 SMP PREEMPT Thu Jul 17 16:19:36 BST 2014
> > CPU: AArch64 Processor [410fd070] revision 0
> > Early serial console at I/O port 0x0 (options '')
> > bootconsole [uart0] enabled
> > efi: Getting parameters from FDT:
> > efi: Can't find System Table in device tree!
> > cma: CMA: failed to reserve 512 MiB
> > psci: probing for conduit method from DT.
> > psci: Using PSCI v0.1 Function IDs from DT
> > PERCPU: Embedded 1 pages/cpu @fffffe0023e80000 s13120 r8192 d44224 u65536
> > Built 1 zonelists in Zone order, mobility grouping off. Total pages: 9208
> > Kernel command line: console=hvc0,38400 earlycon=uart8250,0x3f8 root=/dev/root rw rootflags=rw,trans=virtio,version=9p2000.L rootfstype=9p init=/virt/init ip=dhcp
> > PID hash table entries: 4096 (order: -1, 32768 bytes)
> > Dentry cache hash table entries: 131072 (order: 4, 1048576 bytes)
> > Inode-cache hash table entries: 65536 (order: 3, 524288 bytes)
> > Memory: 579264K/589824K available (4359K kernel code, 455K rwdata, 1536K rodata, 332K init, 280K bss, 10560K reserved)
> > Virtual kernel memory layout:
> > vmalloc : 0xfffffc0000000000 - 0xfffffdfbffff0000 (2080767 MB)
> > vmemmap : 0xfffffdfc001c0000 - 0xfffffdfc0023e000 ( 0 MB)
> > modules : 0xfffffdfffc000000 - 0xfffffe0000000000 ( 64 MB)
> > memory : 0xfffffe0000000000 - 0xfffffe0024000000 ( 576 MB)
> > .init : 0xfffffe0000660000 - 0xfffffe00006b3340 ( 333 kB)
> > .text : 0xfffffe0000080000 - 0xfffffe0000651f94 ( 5960 kB)
> > .data : 0xfffffe00006c0000 - 0xfffffe0000731ca8 ( 456 kB)
> > SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
> > Preemptible hierarchical RCU implementation.
> > RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
> > RCU: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
> > NR_IRQS:64 nr_irqs:64 0
>
> Not a lot to go on there. If you get desperate you can configure FTRACE
> and pass "ftrace=function ftrace_dump_on_oops" as additional additional
> kernel command line arguments. If you get really desperate you can do
> the same on the host. Just beware the output is really long.
Cheers for the replies. It could be that I'm tickling something with kvmtool
that qemu doesn't do, so I'll add some traces and try to figure out some more
information later on today.
Will
^ permalink raw reply
* [PATCH 4/5] tty: serial: 8250 core: add runtime pm
From: Sebastian Andrzej Siewior @ 2014-07-18 8:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140717161848.GK10459@saruman.home>
On 07/17/2014 06:18 PM, Felipe Balbi wrote:
>> No, this is okay. If you look, it checks for "up->ier &
>> UART_IER_THRI". On the second invocation it will see that this
>> bit is already set and therefore won't call get_sync() for the
>> second time. That bit is removed in the _stop_tx() path.
>
> oh, right. But that's actually unnecessary. Calling
> pm_runtime_get() multiple times will just increment the usage
> counter multiple times, which means you can call __stop_tx()
> multiple times too and everything gets balanced, right ?
No. start_tx() will be called multiple times but only the first
invocation invoke pm_runtime_get(). Now I noticed that I forgot to
remove pm_runtime_put_autosuspend() at the bottom of it. But you get
the idea right?
pm_get() on the while the UART_IER_THRI is not yet set. pm_put() once
the fifo is completely empty.
>> Do you have other ideas? It doesn't look like this is exported at
>> all. If we call _stop_tx() right away, then we have 64 bytes in
>> the TX fifo in the worst case. They should be gone "soon" but the
>> HW-flow control may delay it (in theory for a long time)).
>
> this can be problematic, specially for OMAP which can go into OFF
> while idle. Whatever is in the FIFO would get lost. It seems like
> omap-serial solved this within transmit_chars().
No, it didn't.
> See how transmit_chars() is called from within IRQ handler with
> clocks enabled then it conditionally calls serial_omap_stop_tx()
> which will pm_runtime_get_sync() -> do_the_harlem_shake() ->
> pm_runtime_put_autosuspend(). That leaves one unbalanced
> pm_runtime_get() which is balanced when we're exitting the IRQ
> handler.
omap-serial and the 8250 do the following on tx path:
- start_tx()
-> sets UART_IER_THRI. This will generate an interrupt once the FIFO
is empty.
- interrupt, notices the empty fifo, invokes serial8250_start_tx()/
transmit_chars().
Both have a while loop that fills the FIFO. This loop is left once
the tty-buffer is empty (uart_circ_empty() is true) or the FIFO full.
Lets say you filled 64 bytes into the FIFO and then left because your
FIFO is full and tty-buffer is empty. That means you will invoke
serial_omap_stop_tx() and remove UART_IER_THRI bit.
This is okay because you are not interested in further FIFO empty
interrupts because you don't have any TX-bytes to be sent. However,
once you leave the transmit_chars() you leave serial_omap_irq() which
does the last pm_put(). That means you have data in the TX FIFO that is
about to be sent and the device is in auto-suspend.
This is "fine" as long as the timeout is greater then the time required
for the data be sent (plus assuming HW-float control does not stall it
for too long) so nobody notices a thing.
For that reason I added the hack / #if0 block in the 8250 driver. To
ensure we do not disable the TX-FIFO-empty interrupt even if there is
nothing to send. Instead we enter serial8250_tx_chars() once again with
empty FIFO and empty tty-buffer and will invoke _stop_tx() which also
finally does the pm_put().
That is the plan. The problem I have is how to figure out that the
device is using auto-suspend. If I don't then I would have to remove
the #if0 block and that would mean for everybody an extra interrupt
(which I wanted to avoid).
> This seems work fine and dandy without DMA, but for DMA work, I
> think we need to make sure this IP stays powered until we get DMA
> completion callback. But that's future, I guess.
Yes, probably. That means one get at dma start, one put at dma complete
callback. And I assume we get that callbacks once the DMA transfer is
complete, not when the FIFO is empty :) So lets leave it to the future
for now?
Sebastian
^ permalink raw reply
* [PATCH] ARM: rockchip: Add cpu hotplug support for RK3XXX SoCs
From: Russell King - ARM Linux @ 2014-07-18 8:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <53C8BBA2.7060308@gmail.com>
On Fri, Jul 18, 2014 at 08:16:02AM +0200, Romain Perier wrote:
> you're probably talking about __cpu_die at
> http://lxr.free-electrons.com/source/arch/arm/kernel/smp.c#L223 . The
> problem being that the thread below which executes cpu_die completes the
> completion before executing smp_ops.cpu_die. So smp_ops.cpu_kill might
> be executed before smp_ops.cpu_die (in some cases cache coherency would
> not be turned off). Note that almost all SoCs do the same thing.
Look at what's happening:
CPU0 CPU1
wait_for_completion_timeout()
idle_task_exit()
flush_cache_louis()
complete(&cpu_died);
At this point, it is safe for CPU1 to be powered down.
smp_ops.cpu_kill(cpu);
flush_cache_louis();
smp_ops.cpu_die(cpu);
If we include your code at that point, then the sequence in totality
becomes:
wait_for_completion_timeout()
idle_task_exit()
flush_cache_louis()
complete(&cpu_died);
--- rockchip_cpu_kill ---
wait_for_completion_timeout()
flush_cache_louis();
--- rockchip_cpu_die ---
complete(&cpu_died);
pmu_set_power_domain(0 + cpu, false);
flush_cache_louis();
v7_exit_coherency_flush(louis);
while(1)
cpu_do_idle();
So, I repeat my question. What is the point of your additional wait
in rockchip_cpu_kill() and complete in rockchip_cpu_die()?
--
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH v7 07/24] mfd: max77686: Remove unneeded OOM error message
From: Lee Jones @ 2014-07-18 8:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1404505467-26526-8-git-send-email-javier.martinez@collabora.co.uk>
On Fri, 04 Jul 2014, Javier Martinez Canillas wrote:
> There is no need to print out-of-memory errors since this is already
> done by the memory management subsystem which even calls dump_stack().
>
> Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> ---
> drivers/mfd/max77686.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
Applied now, thanks.
> diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
> index 87fe52e..8650832 100644
> --- a/drivers/mfd/max77686.c
> +++ b/drivers/mfd/max77686.c
> @@ -107,10 +107,8 @@ static struct max77686_platform_data *max77686_i2c_parse_dt_pdata(struct device
> struct max77686_platform_data *pd;
>
> pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
> - if (!pd) {
> - dev_err(dev, "could not allocate memory for pdata\n");
> + if (!pd)
> return NULL;
> - }
>
> dev->platform_data = pd;
> return pd;
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v7 06/24] mfd: max77686: Make error checking consistent
From: Lee Jones @ 2014-07-18 8:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1404505467-26526-7-git-send-email-javier.martinez@collabora.co.uk>
On Fri, 04 Jul 2014, Javier Martinez Canillas wrote:
> Error checking across the driver is mostly consistent besides
> a few exceptions, so change these exceptions for consistency.
>
> Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
> ---
> drivers/mfd/max77686.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
Applied now, thanks.
> diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
> index ada4976..87fe52e 100644
> --- a/drivers/mfd/max77686.c
> +++ b/drivers/mfd/max77686.c
> @@ -134,7 +134,7 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
>
> max77686 = devm_kzalloc(&i2c->dev,
> sizeof(struct max77686_dev), GFP_KERNEL);
> - if (max77686 == NULL)
> + if (!max77686)
> return -ENOMEM;
>
> i2c_set_clientdata(i2c, max77686);
> @@ -153,8 +153,8 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
> return ret;
> }
>
> - if (regmap_read(max77686->regmap,
> - MAX77686_REG_DEVICE_ID, &data) < 0) {
> + ret = regmap_read(max77686->regmap, MAX77686_REG_DEVICE_ID, &data);
> + if (ret < 0) {
> dev_err(max77686->dev,
> "device not found on this channel (this is not an error)\n");
> return -ENODEV;
> @@ -180,7 +180,7 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
> IRQF_TRIGGER_FALLING | IRQF_ONESHOT |
> IRQF_SHARED, 0, &max77686_irq_chip,
> &max77686->irq_data);
> - if (ret != 0) {
> + if (ret) {
> dev_err(&i2c->dev, "failed to add PMIC irq chip: %d\n", ret);
> goto err_unregister_i2c;
> }
> @@ -188,7 +188,7 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
> IRQF_TRIGGER_FALLING | IRQF_ONESHOT |
> IRQF_SHARED, 0, &max77686_rtc_irq_chip,
> &max77686->rtc_irq_data);
> - if (ret != 0) {
> + if (ret) {
> dev_err(&i2c->dev, "failed to add RTC irq chip: %d\n", ret);
> goto err_del_irqc;
> }
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v7 05/24] mfd: max77686: Return correct error when pdata isn't found
From: Lee Jones @ 2014-07-18 8:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1404505467-26526-6-git-send-email-javier.martinez@collabora.co.uk>
On Fri, 04 Jul 2014, Javier Martinez Canillas wrote:
> When platform data is not found an -EIO (I/O error) code is returned.
> This doesn't seem to be the correct error so better return -EINVAL
> (Invalid argument) which is what most drivers do in this case.
>
> Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> ---
> drivers/mfd/max77686.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Applied now, thanks.
> diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
> index 12d4c17..ada4976 100644
> --- a/drivers/mfd/max77686.c
> +++ b/drivers/mfd/max77686.c
> @@ -129,7 +129,7 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
>
> if (!pdata) {
> dev_err(&i2c->dev, "No platform data found.\n");
> - return -EIO;
> + return -EINVAL;
> }
>
> max77686 = devm_kzalloc(&i2c->dev,
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v7 04/24] mfd: max77686: Make platform data over-rule DT
From: Lee Jones @ 2014-07-18 8:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1404505467-26526-5-git-send-email-javier.martinez@collabora.co.uk>
On Fri, 04 Jul 2014, Javier Martinez Canillas wrote:
> The function max77802_i2c_parse_dt_pdata() should only be called
> if there isn't already platform data for the device.
>
> Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> ---
> drivers/mfd/max77686.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Applied now, thanks.
> diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
> index d1f9d04..12d4c17 100644
> --- a/drivers/mfd/max77686.c
> +++ b/drivers/mfd/max77686.c
> @@ -124,7 +124,7 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
> unsigned int data;
> int ret = 0;
>
> - if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node)
> + if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node && !pdata)
> pdata = max77686_i2c_parse_dt_pdata(&i2c->dev);
>
> if (!pdata) {
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v7 03/24] mfd: max77686: Don't define dummy function if OF isn't enabled
From: Lee Jones @ 2014-07-18 8:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1404505467-26526-4-git-send-email-javier.martinez@collabora.co.uk>
On Fri, 04 Jul 2014, Javier Martinez Canillas wrote:
> When the CONFIG_OF option was not enabled, a dummy function
> max77686_i2c_parse_dt_pdata() was defined since this is called
> unconditionally on probe(). Just always define the real function
> and conditionally call it if CONFIG_OF is enabled instead.
>
> Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> ---
> drivers/mfd/max77686.c | 10 +---------
> 1 file changed, 1 insertion(+), 9 deletions(-)
Applied now, thanks.
> diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
> index a38e9ee..d1f9d04 100644
> --- a/drivers/mfd/max77686.c
> +++ b/drivers/mfd/max77686.c
> @@ -96,7 +96,6 @@ static const struct regmap_irq_chip max77686_rtc_irq_chip = {
> .num_irqs = ARRAY_SIZE(max77686_rtc_irqs),
> };
>
> -#ifdef CONFIG_OF
> static const struct of_device_id max77686_pmic_dt_match[] = {
> {.compatible = "maxim,max77686", .data = NULL},
> {},
> @@ -116,13 +115,6 @@ static struct max77686_platform_data *max77686_i2c_parse_dt_pdata(struct device
> dev->platform_data = pd;
> return pd;
> }
> -#else
> -static struct max77686_platform_data *max77686_i2c_parse_dt_pdata(struct device
> - *dev)
> -{
> - return 0;
> -}
> -#endif
>
> static int max77686_i2c_probe(struct i2c_client *i2c,
> const struct i2c_device_id *id)
> @@ -132,7 +124,7 @@ static int max77686_i2c_probe(struct i2c_client *i2c,
> unsigned int data;
> int ret = 0;
>
> - if (i2c->dev.of_node)
> + if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node)
> pdata = max77686_i2c_parse_dt_pdata(&i2c->dev);
>
> if (!pdata) {
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v7 02/24] mfd: max77686: Add power management support
From: Lee Jones @ 2014-07-18 8:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1404505467-26526-3-git-send-email-javier.martinez@collabora.co.uk>
On Fri, 04 Jul 2014, Javier Martinez Canillas wrote:
> The driver doesn't have PM operations defined so add a suspend
> and resume function handlers to allow the PMIC IRQ to wakeup
> the system when it is put into a sleep state.
>
> Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
> ---
> drivers/mfd/max77686.c | 40 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 40 insertions(+)
Applied now, thanks.
> diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
> index 3cb41d0..a38e9ee 100644
> --- a/drivers/mfd/max77686.c
> +++ b/drivers/mfd/max77686.c
> @@ -240,10 +240,50 @@ static const struct i2c_device_id max77686_i2c_id[] = {
> };
> MODULE_DEVICE_TABLE(i2c, max77686_i2c_id);
>
> +#ifdef CONFIG_PM_SLEEP
> +static int max77686_suspend(struct device *dev)
> +{
> + struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
> + struct max77686_dev *max77686 = i2c_get_clientdata(i2c);
> +
> + if (device_may_wakeup(dev))
> + enable_irq_wake(max77686->irq);
> +
> + /*
> + * IRQ must be disabled during suspend because if it happens
> + * while suspended it will be handled before resuming I2C.
> + *
> + * When device is woken up from suspend (e.g. by RTC wake alarm),
> + * an interrupt occurs before resuming I2C bus controller.
> + * Interrupt handler tries to read registers but this read
> + * will fail because I2C is still suspended.
> + */
> + disable_irq(max77686->irq);
> +
> + return 0;
> +}
> +
> +static int max77686_resume(struct device *dev)
> +{
> + struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
> + struct max77686_dev *max77686 = i2c_get_clientdata(i2c);
> +
> + if (device_may_wakeup(dev))
> + disable_irq_wake(max77686->irq);
> +
> + enable_irq(max77686->irq);
> +
> + return 0;
> +}
> +#endif /* CONFIG_PM_SLEEP */
> +
> +static SIMPLE_DEV_PM_OPS(max77686_pm, max77686_suspend, max77686_resume);
> +
> static struct i2c_driver max77686_i2c_driver = {
> .driver = {
> .name = "max77686",
> .owner = THIS_MODULE,
> + .pm = &max77686_pm,
> .of_match_table = of_match_ptr(max77686_pmic_dt_match),
> },
> .probe = max77686_i2c_probe,
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v7 01/24] mfd: max77686: Convert to use regmap_irq
From: Lee Jones @ 2014-07-18 8:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1404505467-26526-2-git-send-email-javier.martinez@collabora.co.uk>
> By using the generic IRQ support in the Register map API, it
> is possible to get rid max77686-irq.c and simplify the code.
>
> Suggested-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
> Signed-off-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
> Acked-by: Lee Jones <lee.jones@linaro.org>
> Reviewed-by: Doug Anderson <dianders@chromium.org>
> Tested-by: Doug Anderson <dianders@chromium.org>
Applied now, thanks.
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH 5/5] ARM: sunxi: Add A31 RTC driver to sunxi_defconfig
From: Maxime Ripard @ 2014-07-18 8:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1405323137-24287-6-git-send-email-wens@csie.org>
On Mon, Jul 14, 2014 at 03:32:17PM +0800, Chen-Yu Tsai wrote:
> Now that we have a driver for A31's RTC, enable it
> in the default sunxi config.
It would be great if you could do this for multi_v7 as well.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140718/7b00b43d/attachment.sig>
^ permalink raw reply
* [PATCH 2/5] rtc: sunxi: Depend on platforms sun4i/sun7i that actually have the rtc
From: Maxime Ripard @ 2014-07-18 8:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1405323137-24287-3-git-send-email-wens@csie.org>
On Mon, Jul 14, 2014 at 03:32:14PM +0800, Chen-Yu Tsai wrote:
> Now that we have Kconfig options for individual sunxi platforms, let
> the rtc-sunxi driver depend on the platforms that actually have this
> hardware, sun4i and sun7i.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Thanks,
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140718/0a7c12ae/attachment.sig>
^ permalink raw reply
* [PATCH] ARM: versatile: allow enabling PCI for device tree only kernels
From: Michael Olbrich @ 2014-07-18 8:11 UTC (permalink / raw)
To: linux-arm-kernel
This makes it possible to build a device tree only kernel with PCI support.
This is necessary to access the i6300esb watchdog provided by qemu.
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
---
arch/arm/mach-versatile/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
index 1dba368..993ed4b 100644
--- a/arch/arm/mach-versatile/Kconfig
+++ b/arch/arm/mach-versatile/Kconfig
@@ -20,6 +20,7 @@ config MACH_VERSATILE_AB
config MACH_VERSATILE_DT
bool "Support Versatile platform from device tree"
select CPU_ARM926T
+ select MIGHT_HAVE_PCI
select USE_OF
help
Include support for the ARM(R) Versatile/PB platform,
--
2.0.1
^ permalink raw reply related
* [GIT PULL] ARM: imx: fixes for 3.16, 2nd take
From: Shawn Guo @ 2014-07-18 8:07 UTC (permalink / raw)
To: linux-arm-kernel
The following changes since commit 4c834452aad01531db949414f94f817a86348d59:
Linux 3.16-rc3 (2014-06-29 14:11:36 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-fixes-3.16-2
for you to fetch changes up to 03e97220b99b8b691ea5b130b7b4c135c9662792:
ARM: clk-imx6q: parent lvds_sel input from upstream clock gates (2014-07-18 15:57:17 +0800)
----------------------------------------------------------------
The i.MX fixes for 3.16, 2nd take:
It fixes a hard machine hang regression for boards where only pcie is
active but no sata, as the latest imx6-pcie driver is no longer enabling
the upstream clock directly but only lvds clk out.
----------------------------------------------------------------
Lucas Stach (1):
ARM: clk-imx6q: parent lvds_sel input from upstream clock gates
arch/arm/mach-imx/clk-imx6q.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
^ permalink raw reply
* [PATCH 1/5] rtc: sun6i: Add sun6i RTC driver
From: Maxime Ripard @ 2014-07-18 8:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1405323137-24287-2-git-send-email-wens@csie.org>
Hi,
On Mon, Jul 14, 2014 at 03:32:13PM +0800, Chen-Yu Tsai wrote:
> This patch introduces the driver for the RTC in the Allwinner A31 and
> A23 SoCs.
>
> Unlike the RTC found in A10/A20 SoCs, which was part of the timer, the
> RTC in A31/A23 are a separate hardware block, which also contain a few
> controls for the RTC block hardware (a regulator and RTC block GPIO pin
> latches), while also having separate interrupts for the alarms.
Do you plan on supporting those at some point?
It's also worth noting that the first registers are supposed to
control the source of the low frequency oscillator in the SoC, which
will probably be the most troublesome, since we need these clocks very
early on.
>
> The hardware is different enough to make a different driver for it.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
> .../devicetree/bindings/rtc/sun6i-rtc.txt | 17 +
> drivers/rtc/Kconfig | 7 +
> drivers/rtc/Makefile | 1 +
> drivers/rtc/rtc-sun6i.c | 466 +++++++++++++++++++++
> 4 files changed, 491 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
> create mode 100644 drivers/rtc/rtc-sun6i.c
>
> diff --git a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
> new file mode 100644
> index 0000000..b18927c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt
> @@ -0,0 +1,17 @@
> +* sun6i Real Time Clock
> +
> +RTC controller for the Allwinner A31
> +
> +Required properties:
> +- compatible : Should be "allwinner,sun6i-a31-rtc"
> +- reg: physical base address of the controller and length of memory mapped
> + region.
> +- interrupts: IRQ line for the RTC alarm 0.
> +
> +Example:
> +
> +rtc: rtc at 01f00000 {
> + compatible = "allwinner,sun6i-a31-rtc";
> + reg = <0x01f00000 0x54>;
> + interrupts = <0 40 4>;
> +};
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 0754f5c..5b3910a 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -1167,6 +1167,13 @@ config RTC_DRV_SUN4V
> If you say Y here you will get support for the Hypervisor
> based RTC on SUN4V systems.
>
> +config RTC_DRV_SUN6I
> + tristate "Allwinner sun6i/sun8i RTC"
I'm half convinced about an exhaustive list here. That IP will also
probably be used by sun9i, and sun10i if it ever exists, etc. And you
exhaustive list won't be anymore.
I'd rather just mention the A31, like we do for the DT.
> + depends on MACH_SUN6I || MACH_SUN8I
> + help
> + If you say Y here you will get support for the RTC found on
> + Allwinner A31/A23.
> +
> config RTC_DRV_SUNXI
> tristate "Allwinner sun4i/sun7i RTC"
> depends on ARCH_SUNXI
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index 70347d0..a47df29 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -123,6 +123,7 @@ obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
> obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
> obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o
> obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o
> +obj-$(CONFIG_RTC_DRV_SUN6I) += rtc-sun6i.o
> obj-$(CONFIG_RTC_DRV_SUNXI) += rtc-sunxi.o
> obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o
> obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
> diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
> new file mode 100644
> index 0000000..fabd019
> --- /dev/null
> +++ b/drivers/rtc/rtc-sun6i.c
> @@ -0,0 +1,466 @@
> +/*
> + * An RTC driver for Allwinner A31/A23
> + *
> + * Copyright (c) 2014, Chen-Yu Tsai <wens@csie.org>
> + *
> + * based on rtc-sunxi.c
> + *
> + * An RTC driver for Allwinner A10/A20
> + *
> + * Copyright (c) 2013, Carlo Caione <carlo.caione@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/fs.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/rtc.h>
> +#include <linux/types.h>
> +
> +/* Control register */
> +#define SUN6I_LOSC_CTRL 0x0000
> +#define SUN6I_LOSC_CTRL_ALM_DHMS_ACC BIT(9)
> +#define SUN6I_LOSC_CTRL_RTC_HMS_ACC BIT(8)
> +#define SUN6I_LOSC_CTRL_RTC_YMD_ACC BIT(7)
> +#define SUN6I_LOSC_CTRL_ACC_MASK (BIT(9) | BIT(8) | BIT(7))
GENMASK maybe?
> +
> +/* RTC */
> +#define SUN6I_RTC_YMD 0x0010
> +#define SUN6I_RTC_HMS 0x0014
> +
> +/* Alarm 0 (counter) */
> +#define SUN6I_ALRM_COUNTER 0x0020
> +#define SUN6I_ALRM_CUR_VAL 0x0024
> +#define SUN6I_ALRM_EN 0x0028
> +#define SUN6I_ALRM_EN_CNT_EN BIT(0)
> +#define SUN6I_ALRM_IRQ_EN 0x002c
> +#define SUN6I_ALRM_IRQ_EN_CNT_IRQ_EN BIT(0)
> +#define SUN6I_ALRM_IRQ_STA 0x0030
> +#define SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND BIT(0)
> +
> +/* Alarm 1 (wall clock) */
> +#define SUN6I_ALRM1_EN 0x0044
> +#define SUN6I_ALRM1_IRQ_EN 0x0048
> +#define SUN6I_ALRM1_IRQ_STA 0x004c
> +#define SUN6I_ALRM1_IRQ_STA_WEEK_IRQ_PEND BIT(0)
> +
> +/* Alarm config */
> +#define SUN6I_ALARM_CONFIG 0x0050
> +#define SUN6I_ALARM_CONFIG_WAKEUP BIT(0)
> +
> +/* days / hours are 5 bit wide */
> +#define SUN6I_MASK_DH 0x0000001f
> +/* seconds / minutes / years are 6 bit wide */
> +#define SUN6I_MASK_SMY 0x0000003f
> +/* months are 4 bit wide */
> +#define SUN6I_MASK_M 0x0000000f
> +/* leap year is single bit */
> +#define SUN6I_MASK_LY 0x00000001
Ditto
> +
> +#define SUN6I_GET(x, mask, shift) (((x) & ((mask) << (shift))) \
> + >> (shift))
> +
> +#define SUN6I_SET(x, mask, shift) (((x) & (mask)) << (shift))
Wouldn't it be easier to have the mask already shifted?
> +
> +/*
> + * Get date values
> + */
> +#define SUN6I_DATE_GET_DAY_VALUE(x) SUN6I_GET(x, SUN6I_MASK_DH, 0)
> +#define SUN6I_DATE_GET_MON_VALUE(x) SUN6I_GET(x, SUN6I_MASK_M, 8)
> +#define SUN6I_DATE_GET_YEAR_VALUE(x) SUN6I_GET(x, SUN6I_MASK_SMY, 16)
> +
> +/*
> + * Get time values
> + */
> +#define SUN6I_TIME_GET_SEC_VALUE(x) SUN6I_GET(x, SUN6I_MASK_SMY, 0)
> +#define SUN6I_TIME_GET_MIN_VALUE(x) SUN6I_GET(x, SUN6I_MASK_SMY, 8)
> +#define SUN6I_TIME_GET_HOUR_VALUE(x) SUN6I_GET(x, SUN6I_MASK_DH, 16)
> +
> +/*
> + * Set date values
> + */
> +#define SUN6I_DATE_SET_DAY_VALUE(x) SUN6I_DATE_GET_DAY_VALUE(x)
> +#define SUN6I_DATE_SET_MON_VALUE(x) SUN6I_SET(x, SUN6I_MASK_M, 8)
> +#define SUN6I_DATE_SET_YEAR_VALUE(x) SUN6I_SET(x, SUN6I_MASK_SMY, 16)
> +#define SUN6I_LEAP_SET_VALUE(x) SUN6I_SET(x, SUN6I_MASK_LY, 22)
> +
> +/*
> + * Set time values
> + */
> +#define SUN6I_TIME_SET_SEC_VALUE(x) SUN6I_TIME_GET_SEC_VALUE(x)
> +#define SUN6I_TIME_SET_MIN_VALUE(x) SUN6I_SET(x, SUN6I_MASK_SMY, 8)
> +#define SUN6I_TIME_SET_HOUR_VALUE(x) SUN6I_SET(x, SUN6I_MASK_DH, 16)
> +
> +/*
> + * The year parameter passed to the driver is usually an offset relative to
> + * the year 1900. This macro is used to convert this offset to another one
> + * relative to the minimum year allowed by the hardware.
> + *
> + * The year range is 1970 - 2033. This range is selected to match Allwinner's
> + * driver, even though it is somewhat limited.
> + */
> +#define SUN6I_YEAR_MIN 1970
> +#define SUN6I_YEAR_MAX 2033
> +#define SUN6I_YEAR_OFF (SUN6I_YEAR_MIN - 1900)
> +
> +struct sun6i_rtc_dev {
> + struct rtc_device *rtc;
> + struct device *dev;
> + void __iomem *base;
> + int irq;
> + unsigned long alarm;
> +};
> +
> +static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
> +{
> + struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id;
> + u32 val;
> +
> + val = readl(chip->base + SUN6I_ALRM_IRQ_STA);
> +
> + if (val & SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND) {
> + val |= SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND;
> + writel(val, chip->base + SUN6I_ALRM_IRQ_STA);
> +
> + rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF);
> +
> + return IRQ_HANDLED;
> + }
> +
> + return IRQ_NONE;
> +}
> +
> +static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
> +{
> + u32 alrm_val = 0;
> + u32 alrm_irq_val = 0;
> + u32 alrm_wake_val = 0;
> +
> + if (to) {
> + alrm_val = SUN6I_ALRM_EN_CNT_EN;
> + alrm_irq_val = SUN6I_ALRM_IRQ_EN_CNT_IRQ_EN;
> + alrm_wake_val = SUN6I_ALARM_CONFIG_WAKEUP;
> + } else {
> + writel(SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND,
> + chip->base + SUN6I_ALRM_IRQ_STA);
> + }
> +
> + writel(alrm_val, chip->base + SUN6I_ALRM_EN);
> + writel(alrm_irq_val, chip->base + SUN6I_ALRM_IRQ_EN);
> + writel(alrm_wake_val, chip->base + SUN6I_ALARM_CONFIG);
> +}
> +
> +static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
> +{
> + struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
> + u32 date, time;
> +
> + /*
> + * read again in case it changes
> + */
> + do {
> + date = readl(chip->base + SUN6I_RTC_YMD);
> + time = readl(chip->base + SUN6I_RTC_HMS);
> + } while ((date != readl(chip->base + SUN6I_RTC_YMD)) ||
> + (time != readl(chip->base + SUN6I_RTC_HMS)));
> +
> + rtc_tm->tm_sec = SUN6I_TIME_GET_SEC_VALUE(time);
> + rtc_tm->tm_min = SUN6I_TIME_GET_MIN_VALUE(time);
> + rtc_tm->tm_hour = SUN6I_TIME_GET_HOUR_VALUE(time);
> +
> + rtc_tm->tm_mday = SUN6I_DATE_GET_DAY_VALUE(date);
> + rtc_tm->tm_mon = SUN6I_DATE_GET_MON_VALUE(date);
> + rtc_tm->tm_year = SUN6I_DATE_GET_YEAR_VALUE(date);
> +
> + rtc_tm->tm_mon -= 1;
> +
> + /*
> + * switch from (data_year->min)-relative offset to
> + * a (1900)-relative one
> + */
I guess the reference to the structure field is not relevant anymore
> + rtc_tm->tm_year += SUN6I_YEAR_OFF;
> +
> + return rtc_valid_tm(rtc_tm);
> +}
> +
> +static int sun6i_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
> +{
> + struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
> + u32 alrm_st;
> + u32 alrm_en;
> +
> + alrm_en = readl(chip->base + SUN6I_ALRM_IRQ_EN);
> + alrm_st = readl(chip->base + SUN6I_ALRM_IRQ_STA);
> + wkalrm->enabled = !!(alrm_en & SUN6I_ALRM_EN_CNT_EN);
> + wkalrm->pending = !!(alrm_st & SUN6I_ALRM_EN_CNT_EN);
> + rtc_time_to_tm(chip->alarm, &wkalrm->time);
> +
> + return 0;
> +}
> +
> +static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
> +{
> + struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
> + struct rtc_time *alrm_tm = &wkalrm->time;
> + struct rtc_time tm_now;
> + unsigned long time_now = 0;
> + unsigned long time_set = 0;
> + unsigned long time_gap = 0;
> + int ret = 0;
> +
> + ret = sun6i_rtc_gettime(dev, &tm_now);
> + if (ret < 0) {
> + dev_err(dev, "Error in getting time\n");
> + return -EINVAL;
> + }
> +
> + rtc_tm_to_time(alrm_tm, &time_set);
> + rtc_tm_to_time(&tm_now, &time_now);
> + if (time_set <= time_now) {
> + dev_err(dev, "Date to set in the past\n");
> + return -EINVAL;
> + }
> +
> + time_gap = time_set - time_now;
> +
> + if (time_gap > U32_MAX) {
> + dev_err(dev, "Date too far in the future\n");
> + return -EINVAL;
> + }
> +
> + sun6i_rtc_setaie(0, chip);
> + writel(0, chip->base + SUN6I_ALRM_COUNTER);
> + usleep_range(100, 300);
> +
> + writel(time_gap, chip->base + SUN6I_ALRM_COUNTER);
> + chip->alarm = time_set;
> +
> + sun6i_rtc_setaie(wkalrm->enabled, chip);
> +
> + return 0;
> +}
> +
> +static int sun6i_rtc_wait(struct sun6i_rtc_dev *chip, int offset,
> + unsigned int mask, unsigned int ms_timeout)
> +{
> + const unsigned long timeout = jiffies + msecs_to_jiffies(ms_timeout);
> + u32 reg;
> +
> + do {
> + reg = readl(chip->base + offset);
> + reg &= mask;
> +
> + if (!reg)
> + return 0;
> +
> + } while (time_before(jiffies, timeout));
> +
> + return -ETIMEDOUT;
> +}
> +
> +static int sun6i_rtc_settime(struct device *dev, struct rtc_time *rtc_tm)
> +{
> + struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
> + u32 date = 0;
> + u32 time = 0;
> + int year;
> +
> + /*
> + * the input rtc_tm->tm_year is the offset relative to 1900. We use
> + * the SUN6I_YEAR_OFF macro to rebase it with respect to the min year
> + * allowed by the hardware
> + */
> +
> + year = rtc_tm->tm_year + 1900;
> + if (year < SUN6I_YEAR_MIN || year > SUN6I_YEAR_MAX) {
> + dev_err(dev, "rtc only supports year in range %d - %d\n",
> + SUN6I_YEAR_MIN, SUN6I_YEAR_MAX);
> + return -EINVAL;
> + }
> +
> + rtc_tm->tm_year -= SUN6I_YEAR_OFF;
> + rtc_tm->tm_mon += 1;
> +
> + date = SUN6I_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) |
> + SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon) |
> + SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year);
> +
> + if (is_leap_year(year))
> + date |= SUN6I_LEAP_SET_VALUE(1);
> +
> + time = SUN6I_TIME_SET_SEC_VALUE(rtc_tm->tm_sec) |
> + SUN6I_TIME_SET_MIN_VALUE(rtc_tm->tm_min) |
> + SUN6I_TIME_SET_HOUR_VALUE(rtc_tm->tm_hour);
> +
> + /* Check whether registers are writable */
> + if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
> + SUN6I_LOSC_CTRL_ACC_MASK, 50)) {
> + dev_err(dev, "rtc is still busy.\n");
> + return -EBUSY;
> + }
> +
> + writel(time, chip->base + SUN6I_RTC_HMS);
> +
> + /*
> + * After writing the RTC HH-MM-SS register, the
> + * SUN6I_LOSC_CTRL_RTC_HMS_ACC bit is set and it will not
> + * be cleared until the real writing operation is finished
> + */
> +
> + if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
> + SUN6I_LOSC_CTRL_RTC_HMS_ACC, 50)) {
> + dev_err(dev, "Failed to set rtc time.\n");
> + return -ETIMEDOUT;
> + }
> +
> + writel(date, chip->base + SUN6I_RTC_YMD);
> +
> + /*
> + * After writing the RTC YY-MM-DD register, the
> + * SUN6I_LOSC_CTRL_RTC_YMD_ACC bit is set and it will not
> + * be cleared until the real writing operation is finished
> + */
> +
> + if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL,
> + SUN6I_LOSC_CTRL_RTC_YMD_ACC, 50)) {
> + dev_err(dev, "Failed to set rtc time.\n");
> + return -ETIMEDOUT;
> + }
> +
> + return 0;
> +}
> +
> +static int sun6i_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
> +{
> + struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
> +
> + if (!enabled)
> + sun6i_rtc_setaie(enabled, chip);
> +
> + return 0;
> +}
> +
> +static const struct rtc_class_ops sun6i_rtc_ops = {
> + .read_time = sun6i_rtc_gettime,
> + .set_time = sun6i_rtc_settime,
> + .read_alarm = sun6i_rtc_getalarm,
> + .set_alarm = sun6i_rtc_setalarm,
> + .alarm_irq_enable = sun6i_rtc_alarm_irq_enable
> +};
> +
> +static const struct of_device_id sun6i_rtc_dt_ids[] = {
> + { .compatible = "allwinner,sun6i-a31-rtc" },
> + { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
I guess you can move this down just before the platform_driver
declaration if you don't need it in probe.
> +
> +static int sun6i_rtc_probe(struct platform_device *pdev)
> +{
> + struct sun6i_rtc_dev *chip;
> + struct resource *res;
> + int ret;
> +
> + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
> + if (!chip)
> + return -ENOMEM;
> +
> + platform_set_drvdata(pdev, chip);
> + chip->dev = &pdev->dev;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + chip->base = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(chip->base))
> + return PTR_ERR(chip->base);
> +
> + chip->irq = platform_get_irq(pdev, 0);
> + if (chip->irq < 0) {
> + dev_err(&pdev->dev, "No IRQ resource\n");
> + return chip->irq;
> + }
Newline
> + ret = devm_request_irq(&pdev->dev, chip->irq, sun6i_rtc_alarmirq,
> + 0, dev_name(&pdev->dev), chip);
> + if (ret) {
> + dev_err(&pdev->dev, "Could not request IRQ\n");
> + return ret;
> + }
> +
> + /* clear the alarm counter value */
> + writel(0, chip->base + SUN6I_ALRM_COUNTER);
> +
> + /* disable counter alarm */
> + writel(0, chip->base + SUN6I_ALRM_EN);
> +
> + /* disable counter alarm interrupt */
> + writel(0, chip->base + SUN6I_ALRM_IRQ_EN);
> +
> + /* disable week alarm */
> + writel(0, chip->base + SUN6I_ALRM1_EN);
> +
> + /* disable week alarm interrupt */
> + writel(0, chip->base + SUN6I_ALRM1_IRQ_EN);
> +
> + /* clear counter alarm pending interrupts */
> + writel(SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND, chip->base +
> + SUN6I_ALRM_IRQ_STA);
> +
> + /* clear week alarm pending interrupts */
> + writel(SUN6I_ALRM1_IRQ_STA_WEEK_IRQ_PEND, chip->base +
> + SUN6I_ALRM1_IRQ_STA);
> +
> + /* disable alarm wakeup */
> + writel(0, chip->base + SUN6I_ALARM_CONFIG);
> +
> + chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev,
> + &sun6i_rtc_ops, THIS_MODULE);
> + if (IS_ERR(chip->rtc)) {
> + dev_err(&pdev->dev, "unable to register device\n");
> + return PTR_ERR(chip->rtc);
> + }
> +
> + dev_info(&pdev->dev, "RTC enabled\n");
> +
> + return 0;
> +}
> +
> +static int sun6i_rtc_remove(struct platform_device *pdev)
> +{
> + struct sun6i_rtc_dev *chip = platform_get_drvdata(pdev);
> +
> + rtc_device_unregister(chip->rtc);
> +
> + return 0;
> +}
> +
> +static struct platform_driver sun6i_rtc_driver = {
> + .probe = sun6i_rtc_probe,
> + .remove = sun6i_rtc_remove,
> + .driver = {
> + .name = "sun6i-rtc",
> + .owner = THIS_MODULE,
> + .of_match_table = sun6i_rtc_dt_ids,
> + },
> +};
> +
> +module_platform_driver(sun6i_rtc_driver);
> +
> +MODULE_DESCRIPTION("sun6i RTC driver");
> +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
> +MODULE_LICENSE("GPL");
> --
> 2.0.1
>
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140718/8fc8491b/attachment-0001.sig>
^ permalink raw reply
* [PATCH] arm: clk-imx6q: parent lvds_sel input from upstream clock gates
From: Shawn Guo @ 2014-07-18 7:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140717150826.GT2197@dragon>
On Thu, Jul 17, 2014 at 11:08:28PM +0800, Shawn Guo wrote:
> On Thu, Jul 17, 2014 at 12:20:14PM +0200, Lucas Stach wrote:
> > The i.MX6 reference manual doesn't make a clear distinction
> > between the fixed clock divider and the enable gate for the
> > pcie and sata reference clocks. This lead to the lvds mux
> > inputs in the imx6q clk driver to be parented from the
> > ref clock (which is the divider) instead of the actual gate,
> > which in turn prevents the upstream clock to actually be
> > enabled when lvds clk out is active.
> >
> > This fixes a hard machine hang regression in kernel 3.16 for
> > boards where only pcie is active but no sata, as with this
> > kernel version the imx6-pcie driver is no longer enabling
> > the upstream clock directly but only lvds clk out.
> >
> > Reported-by: Arne Ruhnau <arne.ruhnau@target-sg.com>
> > Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> > Tested-by: Arne Ruhnau <arne.ruhnau@target-sg.com>
> > ---
> > Shawn, this is an urgent fix for 3.16. Can you please
> > Ack it so arm-soc people can take this directly?
> > ---
>
> Acked-by: Shawn Guo <shawn.guo@freescale.com>
>
> It will conflict with the patch switching to use macro for clock IDs,
> which I'm about to send for 3.17, though.
Arnd, Olof,
Please do not apply the patch manually. I will send you a git tag for
it, so that I can sort out the conflict in my tree.
Shawn
^ permalink raw reply
* [PATCH v5 7/7] arm/arm64: Unexport restart handlers
From: Guenter Roeck @ 2014-07-18 7:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1405668856-13738-1-git-send-email-linux@roeck-us.net>
Implementing a restart handler in a module don't make sense
as there would be no guarantee that the module is loaded when
a restart is needed. Unexport arm_pm_restart to ensure that
no one gets the idea to do it anyway.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v5: No change
v4: No change
v3: No change
v2: No change
arch/arm/kernel/process.c | 1 -
arch/arm64/kernel/process.c | 1 -
2 files changed, 2 deletions(-)
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 84ca0d5..27bdf11 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -125,7 +125,6 @@ void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd) = null_restart;
-EXPORT_SYMBOL_GPL(arm_pm_restart);
/*
* This is our default idle handler.
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 9591e60..f5fddff 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -92,7 +92,6 @@ void (*pm_power_off)(void);
EXPORT_SYMBOL_GPL(pm_power_off);
void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
-EXPORT_SYMBOL_GPL(arm_pm_restart);
/*
* This is our default idle handler.
--
1.9.1
^ permalink raw reply related
* [PATCH v5 6/7] watchdog: alim7101: Register restart handler with kernel restart handler
From: Guenter Roeck @ 2014-07-18 7:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1405668856-13738-1-git-send-email-linux@roeck-us.net>
The kernel core now provides an API to trigger a system restart.
Register with it to restart the system instead of misusing the
reboot notifier.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v5: Function and variable renames: *notifier -> *handler
v4: Set restart notifier priority to 128.
v3: No change
v2: No change
drivers/watchdog/alim7101_wdt.c | 42 +++++++++++++++++++++++++++++++----------
1 file changed, 32 insertions(+), 10 deletions(-)
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index 996b2f7..665e0e7 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -301,6 +301,28 @@ static struct miscdevice wdt_miscdev = {
.fops = &wdt_fops,
};
+static int wdt_restart_handle(struct notifier_block *this, unsigned long mode,
+ void *cmd)
+{
+ /*
+ * Cobalt devices have no way of rebooting themselves other
+ * than getting the watchdog to pull reset, so we restart the
+ * watchdog on reboot with no heartbeat.
+ */
+ wdt_change(WDT_ENABLE);
+
+ /* loop until the watchdog fires */
+ while (true)
+ ;
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block wdt_restart_handler = {
+ .notifier_call = wdt_restart_handle,
+ .priority = 128,
+};
+
/*
* Notifier for system down
*/
@@ -311,15 +333,6 @@ static int wdt_notify_sys(struct notifier_block *this,
if (code == SYS_DOWN || code == SYS_HALT)
wdt_turnoff();
- if (code == SYS_RESTART) {
- /*
- * Cobalt devices have no way of rebooting themselves other
- * than getting the watchdog to pull reset, so we restart the
- * watchdog on reboot with no heartbeat
- */
- wdt_change(WDT_ENABLE);
- pr_info("Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second\n");
- }
return NOTIFY_DONE;
}
@@ -338,6 +351,7 @@ static void __exit alim7101_wdt_unload(void)
/* Deregister */
misc_deregister(&wdt_miscdev);
unregister_reboot_notifier(&wdt_notifier);
+ unregister_restart_handler(&wdt_restart_handler);
pci_dev_put(alim7101_pmu);
}
@@ -390,11 +404,17 @@ static int __init alim7101_wdt_init(void)
goto err_out;
}
+ rc = register_restart_handler(&wdt_restart_handler);
+ if (rc) {
+ pr_err("cannot register restart handler (err=%d)\n", rc);
+ goto err_out_reboot;
+ }
+
rc = misc_register(&wdt_miscdev);
if (rc) {
pr_err("cannot register miscdev on minor=%d (err=%d)\n",
wdt_miscdev.minor, rc);
- goto err_out_reboot;
+ goto err_out_restart;
}
if (nowayout)
@@ -404,6 +424,8 @@ static int __init alim7101_wdt_init(void)
timeout, nowayout);
return 0;
+err_out_restart:
+ unregister_restart_handler(&wdt_restart_handler);
err_out_reboot:
unregister_reboot_notifier(&wdt_notifier);
err_out:
--
1.9.1
^ permalink raw reply related
* [PATCH v5 5/7] watchdog: moxart: Register restart handler with kernel restart handler
From: Guenter Roeck @ 2014-07-18 7:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1405668856-13738-1-git-send-email-linux@roeck-us.net>
The kernel now provides an API to trigger a system restart.
Register with it instead of setting arm_pm_restart.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v5: Functions and variables renamed: *notifier -> *handler
v4: Set notifier priority to 128.
v3: Move struct notifier_block into struct moxart_wdt_dev.
Drop static variable previously needed to access struct moxart_wdt_dev
from notifier function; use container_of instead.
v2: No change.
drivers/watchdog/moxart_wdt.c | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)
diff --git a/drivers/watchdog/moxart_wdt.c b/drivers/watchdog/moxart_wdt.c
index 4aa3a8a..a64405b 100644
--- a/drivers/watchdog/moxart_wdt.c
+++ b/drivers/watchdog/moxart_wdt.c
@@ -15,12 +15,12 @@
#include <linux/module.h>
#include <linux/err.h>
#include <linux/kernel.h>
+#include <linux/notifier.h>
#include <linux/platform_device.h>
+#include <linux/reboot.h>
#include <linux/watchdog.h>
#include <linux/moduleparam.h>
-#include <asm/system_misc.h>
-
#define REG_COUNT 0x4
#define REG_MODE 0x8
#define REG_ENABLE 0xC
@@ -29,17 +29,22 @@ struct moxart_wdt_dev {
struct watchdog_device dev;
void __iomem *base;
unsigned int clock_frequency;
+ struct notifier_block restart_handler;
};
-static struct moxart_wdt_dev *moxart_restart_ctx;
-
static int heartbeat;
-static void moxart_wdt_restart(enum reboot_mode reboot_mode, const char *cmd)
+static int moxart_restart_handle(struct notifier_block *this,
+ unsigned long mode, void *cmd)
{
- writel(1, moxart_restart_ctx->base + REG_COUNT);
- writel(0x5ab9, moxart_restart_ctx->base + REG_MODE);
- writel(0x03, moxart_restart_ctx->base + REG_ENABLE);
+ struct moxart_wdt_dev *moxart_wdt = container_of(this,
+ struct moxart_wdt_dev,
+ restart_handler);
+ writel(1, moxart_wdt->base + REG_COUNT);
+ writel(0x5ab9, moxart_wdt->base + REG_MODE);
+ writel(0x03, moxart_wdt->base + REG_ENABLE);
+
+ return NOTIFY_DONE;
}
static int moxart_wdt_stop(struct watchdog_device *wdt_dev)
@@ -136,8 +141,12 @@ static int moxart_wdt_probe(struct platform_device *pdev)
if (err)
return err;
- moxart_restart_ctx = moxart_wdt;
- arm_pm_restart = moxart_wdt_restart;
+ moxart_wdt->restart_handler.notifier_call = moxart_restart_handle;
+ moxart_wdt->restart_handler.priority = 128;
+ err = register_restart_handler(&moxart_wdt->restart_handler);
+ if (err)
+ dev_err(dev, "cannot register restart notifier (err=%d)\n",
+ err);
dev_dbg(dev, "Watchdog enabled (heartbeat=%d sec, nowayout=%d)\n",
moxart_wdt->dev.timeout, nowayout);
@@ -149,9 +158,8 @@ static int moxart_wdt_remove(struct platform_device *pdev)
{
struct moxart_wdt_dev *moxart_wdt = platform_get_drvdata(pdev);
- arm_pm_restart = NULL;
+ unregister_restart_handler(&moxart_wdt->restart_handler);
moxart_wdt_stop(&moxart_wdt->dev);
- watchdog_unregister_device(&moxart_wdt->dev);
return 0;
}
--
1.9.1
^ permalink raw reply related
* [PATCH v5 4/7] power/restart: Call machine_restart instead of arm_pm_restart
From: Guenter Roeck @ 2014-07-18 7:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1405668856-13738-1-git-send-email-linux@roeck-us.net>
machine_restart is supported on non-ARM platforms, and and ultimately calls
arm_pm_restart, so dont call arm_pm_restart directly but use the more
generic function.
Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v5: No change.
v4: No change.
v3: No change.
v2: Added patch.
drivers/power/reset/restart-poweroff.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/power/reset/restart-poweroff.c b/drivers/power/reset/restart-poweroff.c
index 5758033..47f10eb 100644
--- a/drivers/power/reset/restart-poweroff.c
+++ b/drivers/power/reset/restart-poweroff.c
@@ -20,7 +20,8 @@
static void restart_poweroff_do_poweroff(void)
{
- arm_pm_restart(REBOOT_HARD, NULL);
+ reboot_mode = REBOOT_HARD;
+ machine_restart(NULL);
}
static int restart_poweroff_probe(struct platform_device *pdev)
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox