* [PATCH] mmc: mvsdio: Replace IS_ERR_NULL() is with IS_ERR()
From: Thomas Petazzoni @ 2013-01-11 11:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130111110210.GC30875@n2100.arm.linux.org.uk>
Dear Russell King - ARM Linux,
On Fri, 11 Jan 2013 11:02:10 +0000, Russell King - ARM Linux wrote:
> What remains? The assumption that GPIO0 means "no GPIO" rather than
> testing with gpio_valid() and the IRQ stuff.
Patches that I have written have been merged by Jason Cooper and while
adding the DT binding for this driver, it also converts it to use the
MMC GPIO helpers from drivers/mmc/core/slot-gpio.c, which makes this
whole GPIO initialization/cleanup a lot simpler.
See:
http://git.infradead.org/users/jcooper/linux.git/commitdiff/c3833fbb117bb1a547d29b27a0de4418fa2d5a5a
http://git.infradead.org/users/jcooper/linux.git/commitdiff/e60a21ed4edb7f33010ab21cefcb20666a9bc7d7
Also, note that Andrew Lunn has sent a v2 of his patch:
Subject: [PATCH v2] mmc: mvsdio: Replace IS_ERR_OR_NULL() with IS_ERR()
Date: Fri, 11 Jan 2013 08:27:52 +0100
Best regards,
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH 07/14] usb: ehci-omap: Instantiate PHY devices if required
From: Roger Quadros @ 2013-01-11 11:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50EFF075.5090203@ti.com>
On 01/11/2013 12:59 PM, Roger Quadros wrote:
> On 01/10/2013 10:48 PM, Alan Stern wrote:
>> On Thu, 10 Jan 2013, Roger Quadros wrote:
>>
>>> If the OMAP's Host controller is in PHY mode then we instantiate
>>> a platform device for the PHY (one for each port in PHY mode) and
>>> hold a reference to it so that we can use the usb_phy API, e.g.
>>> while suspend/resume.
>>>
>>> The platform data for the PHY must be supplied in the newly added
>>> .phy_config parameter in struct usbhs_omap_platform_data.
>>>
>>> The end goal is to move the PHY's reset and power handling code
>>> out of the ehci-omap driver and into the phy driver.
>>
>> As mentioned in another thread, I would prefer to have these changes to
>> ehci-omap.c made after the driver is converted to the new "ehci-hcd is
>> a library" scheme. The patch below does the conversion; it is meant to
>> apply on top of the similar patch for ehci-mxc posted recently on the
>> linux-usb mailing list.
>>
>> After this conversion, the omap_ehci_hcd private data structure doesn't
>> have to be allocated specifically. It can be handled in the same way
>> as the private data structure in the ehci-mxc patch.
>>
>> I haven't even tried to compile this. Please let me know how it works.
>>
>
> Alan,
>
> Thanks for the patch. I've pasted the version that builds and works and
> put you as the Author of the patch, hope it is fine.
>
> I could not find the equivalent ehci-mxc implementation though. Any
> pointers to that? Thanks.
OK I found it. Previously I was searching in the archives :P.
cheers,
-roger
^ permalink raw reply
* [PATCH v7 3/3] Cortex-M3: Add support for exception handling
From: Uwe Kleine-König @ 2013-01-11 11:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350462872-16805-4-git-send-email-u.kleine-koenig@pengutronix.de>
Hello,
On Wed, Oct 17, 2012 at 10:34:32AM +0200, Uwe Kleine-K?nig wrote:
> +/*
> + * Register switch for ARMv7-M processors.
> + * r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info
> + * previous and next are guaranteed not to be the same.
> + */
> +ENTRY(__switch_to)
> + .fnstart
> + .cantunwind
> + add ip, r1, #TI_CPU_SAVE
> + stmia ip!, {r4 - r11} @ Store most regs on stack
> + str sp, [ip], #4
> + str lr, [ip], #4
> + mov r5, r0
> + add r4, r2, #TI_CPU_SAVE
> + ldr r0, =thread_notify_head
> + mov r1, #THREAD_NOTIFY_SWITCH
> + bl atomic_notifier_call_chain
> + mov ip, r4
> + mov r0, r5
> + ldmia ip!, {r4 - r11} @ Load all regs saved previously
> + ldr sp, [ip], #4
> + ldr pc, [ip]
> + .fnend
> +ENDPROC(__switch_to)
this code triggers a warning
This instruction may be unpredictable if executed on M-profile
cores with interrupts enabled.
with newer toolchains (seen with gcc 4.7.2) because of errata 752419
(Interrupted loads to SP can cause erroneous behaviour) which badly
affects the following instructions:
ldr sp,[Rn],#imm
ldr sp,[Rn,#imm]!
I think it's not a problem here as irqs are off during task switching,
but when changing
ldr sp, [ip], #4
ldr pc, [ip]
to
ldr sp, [ip]
ldr pc, [ip, #4]!
the result is equivalent and gcc is happy.
I fixed that accordingly in my for-next branch.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH 04/16] ARM: b.L: Add baremetal voting mutexes
From: Will Deacon @ 2013-01-11 11:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1301102131010.6300@xanadu.home>
On Fri, Jan 11, 2013 at 03:15:22AM +0000, Nicolas Pitre wrote:
> On Thu, 10 Jan 2013, Will Deacon wrote:
> > On Thu, Jan 10, 2013 at 12:20:39AM +0000, Nicolas Pitre wrote:
> > > + * vlocks are currently only used to coordinate between CPUs which are
> > > + unable to enable their caches yet. This means that the
> > > + implementation removes many of the barriers which would be required
> > > + when executing the algorithm in cached memory.
> >
> > I think you need to elaborate on this and clearly identify the
> > requirements of the memory behaviour. In reality, these locks are hardly
> > ever usable so we don't want them cropping up in driver code and the
> > like!
>
> Doesn't the following paragraph make that clear enough?
I think it misses a lot out (e.g. we require single-copy atomicity
guarantees for byte access, we require no speculation etc). Essentially,
it's an imprecise definition of strongly-ordered memory. However, see
below (the bit about removing the C implementation)...
> Maybe we should rip out the C interface to avoid such abuses. I think
> that was initially added when we weren't sure if the C code had to be
> involved.
[...]
> > > +#include <linux/linkage.h>
> > > +#include "vlock.h"
> > > +
> > > +#if VLOCK_VOTING_SIZE > 4
> >
> > 4? Maybe a CONFIG option or a #define in an arch vlock.h?
>
> The 4 here is actually related to the number of bytes in a word, to
> decide whether or not a loop is needed for voters enumeration. That is
> not configurable.
BYTES_PER_LONG then (or suitable shifting of BITS_PER_LONG)?
> > > +#define VLOCK_VOTING_SIZE ((BL_CPUS_PER_CLUSTER + 3) / 4 * 4)
> >
> > Huh?
>
> Each ballot is one byte, and we pack them into words. So this is the
> size of the required words to hold all ballots.
Ok, so this could make use of BYTES_PER_LONG too, just to make the reasoning
more clear.
> > > +#define VLOCK_SIZE (VLOCK_VOTING_OFFSET + VLOCK_VOTING_SIZE)
> > > +#define VLOCK_OWNER_NONE 0
> > > +
> > > +#ifndef __ASSEMBLY__
> > > +
> > > +struct vlock {
> > > + char data[VLOCK_SIZE];
> > > +};
> >
> > Does this mean the struct is only single byte aligned? You do word
> > accesses to it in your vlock code and rely on atomicity, so I'd feel
> > safer if it was aligned to 4 bytes, especially since this isn't being
> > accessed via a normal mapping.
>
> The structure size is always a multiple of 4 bytes. Its alignment is
> actually much larger than 4 as it needs to span a whole cache line not
> to be overwritten by dirty line writeback.
That's not implied from the structure definition.
> As I mentioned before, given that this structure is allocated and
> accessed only by assembly code, we could simply remove all those unused
> C definitions to avoid potential confusion and misuse.
Yes, I think removing the C definitions is a great idea. Then, we have a
pure-asm implementation which is, as such, tied to ARM. In that case, the
documentation can just refer to ARM memory types instead of loosely defining
the required characteristics (i.e. state that device or strongly-ordered
memory is required).
Cheers,
Will
^ permalink raw reply
* [PATCH] mmc: mvsdio: Replace IS_ERR_NULL() is with IS_ERR()
From: Russell King - ARM Linux @ 2013-01-11 11:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1357849755-8168-1-git-send-email-andrew@lunn.ch>
On Thu, Jan 10, 2013 at 09:29:15PM +0100, Andrew Lunn wrote:
> A NULL is a valid clk cookie, so we should not be tested with
> IS_ERR_NULL(). Replace it with IS_ERR().
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> drivers/mmc/host/mvsdio.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
> index de4c20b..d0050fa 100644
> --- a/drivers/mmc/host/mvsdio.c
> +++ b/drivers/mmc/host/mvsdio.c
> @@ -839,7 +839,7 @@ out:
> if (r)
> release_resource(r);
> if (mmc)
> - if (!IS_ERR_OR_NULL(host->clk)) {
> + if (!IS_ERR(host->clk)) {
> clk_disable_unprepare(host->clk);
> clk_put(host->clk);
> }
Actually, no.
1. I've already recently pointed out that C is not python, and this code
is broken. (Look at the lack of missing braces around the code you've
modified.)
2. host->clk _can_ be NULL here.
Here's the (untested) bare minimum needed to fix this driver:
drivers/mmc/host/mvsdio.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index de4c20b..4190fb4 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -733,6 +733,7 @@ static int __init mvsd_probe(struct platform_device *pdev)
host->dev = &pdev->dev;
host->res = r;
host->base_clock = mvsd_data->clock / 2;
+ host->clk = ERR_PTR(-EINVAL);
mmc->ops = &mvsd_ops;
@@ -837,13 +838,14 @@ static int __init mvsd_probe(struct platform_device *pdev)
iounmap(host->base);
}
if (r)
- release_resource(r);
- if (mmc)
- if (!IS_ERR_OR_NULL(host->clk)) {
+ release_mem_resource(r->start, resource_size(r));
+ if (mmc) {
+ if (!IS_ERR(host->clk)) {
clk_disable_unprepare(host->clk);
clk_put(host->clk);
}
mmc_free_host(mmc);
+ }
return ret;
}
@@ -866,7 +868,7 @@ static int __exit mvsd_remove(struct platform_device *pdev)
del_timer_sync(&host->timer);
mvsd_power_down(host);
iounmap(host->base);
- release_resource(host->res);
+ release_mem_resource(host->res->start, resource_size(host->res);
if (!IS_ERR(host->clk)) {
clk_disable_unprepare(host->clk);
But... we can do better than that. We have the devm_* APIs which will
make this code simpler, and less prone to these kinds of silly errors.
I've left the request_irq()s alone because it isn't obvious to me that
there isn't a reason for releasing the IRQ at a particular point in the
cleanup, and there's no sign that IRQs may be asked on the device itself.
Note also that I found another bug in this driver - it requests a region
1K in size, but ioremaps 4K. That's just wrong. But anyway, the whole
issue goes away with devm_request_and_ioremap().
What remains? The assumption that GPIO0 means "no GPIO" rather than
testing with gpio_valid() and the IRQ stuff.
drivers/mmc/host/mvsdio.c | 61 +++++++++++++++-----------------------------
1 files changed, 21 insertions(+), 40 deletions(-)
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index de4c20b..4723310 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -50,7 +50,6 @@ struct mvsd_host {
struct timer_list timer;
struct mmc_host *mmc;
struct device *dev;
- struct resource *res;
int irq;
struct clk *clk;
int gpio_card_detect;
@@ -718,10 +717,6 @@ static int __init mvsd_probe(struct platform_device *pdev)
if (!r || irq < 0 || !mvsd_data)
return -ENXIO;
- r = request_mem_region(r->start, SZ_1K, DRIVER_NAME);
- if (!r)
- return -EBUSY;
-
mmc = mmc_alloc_host(sizeof(struct mvsd_host), &pdev->dev);
if (!mmc) {
ret = -ENOMEM;
@@ -731,8 +726,8 @@ static int __init mvsd_probe(struct platform_device *pdev)
host = mmc_priv(mmc);
host->mmc = mmc;
host->dev = &pdev->dev;
- host->res = r;
host->base_clock = mvsd_data->clock / 2;
+ host->clk = ERR_PTR(-EINVAL);
mmc->ops = &mvsd_ops;
@@ -752,7 +747,7 @@ static int __init mvsd_probe(struct platform_device *pdev)
spin_lock_init(&host->lock);
- host->base = ioremap(r->start, SZ_4K);
+ host->base = devm_request_and_ioremap(&pdev->dev, r);
if (!host->base) {
ret = -ENOMEM;
goto out;
@@ -774,16 +769,15 @@ static int __init mvsd_probe(struct platform_device *pdev)
/* Not all platforms can gate the clock, so it is not
an error if the clock does not exists. */
- host->clk = clk_get(&pdev->dev, NULL);
- if (!IS_ERR(host->clk)) {
+ host->clk = devm_clk_get(&pdev->dev, NULL);
+ if (!IS_ERR(host->clk))
clk_prepare_enable(host->clk);
- }
if (mvsd_data->gpio_card_detect) {
- ret = gpio_request(mvsd_data->gpio_card_detect,
- DRIVER_NAME " cd");
+ ret = devm_gpio_request_one(&pdev->dev,
+ mvsd_data->gpio_card_detect,
+ GPIOF_IN, DRIVER_NAME " cd");
if (ret == 0) {
- gpio_direction_input(mvsd_data->gpio_card_detect);
irq = gpio_to_irq(mvsd_data->gpio_card_detect);
ret = request_irq(irq, mvsd_card_detect_irq,
IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING,
@@ -792,17 +786,18 @@ static int __init mvsd_probe(struct platform_device *pdev)
host->gpio_card_detect =
mvsd_data->gpio_card_detect;
else
- gpio_free(mvsd_data->gpio_card_detect);
+ devm_gpio_free(&pdev->dev,
+ mvsd_data->gpio_card_detect);
}
}
if (!host->gpio_card_detect)
mmc->caps |= MMC_CAP_NEEDS_POLL;
if (mvsd_data->gpio_write_protect) {
- ret = gpio_request(mvsd_data->gpio_write_protect,
- DRIVER_NAME " wp");
+ ret = devm_gpio_request_one(&pdev->dev,
+ mvsd_data->gpio_write_protect,
+ GPIOF_IN, DRIVER_NAME " wp");
if (ret == 0) {
- gpio_direction_input(mvsd_data->gpio_write_protect);
host->gpio_write_protect =
mvsd_data->gpio_write_protect;
}
@@ -827,23 +822,15 @@ static int __init mvsd_probe(struct platform_device *pdev)
if (host) {
if (host->irq)
free_irq(host->irq, host);
- if (host->gpio_card_detect) {
+ if (host->gpio_card_detect)
free_irq(gpio_to_irq(host->gpio_card_detect), host);
- gpio_free(host->gpio_card_detect);
- }
- if (host->gpio_write_protect)
- gpio_free(host->gpio_write_protect);
- if (host->base)
- iounmap(host->base);
}
- if (r)
- release_resource(r);
- if (mmc)
- if (!IS_ERR_OR_NULL(host->clk)) {
+ if (mmc) {
+ if (!IS_ERR(host->clk))
clk_disable_unprepare(host->clk);
- clk_put(host->clk);
- }
+
mmc_free_host(mmc);
+ }
return ret;
}
@@ -855,23 +842,17 @@ static int __exit mvsd_remove(struct platform_device *pdev)
if (mmc) {
struct mvsd_host *host = mmc_priv(mmc);
- if (host->gpio_card_detect) {
+ if (host->gpio_card_detect)
free_irq(gpio_to_irq(host->gpio_card_detect), host);
- gpio_free(host->gpio_card_detect);
- }
+
mmc_remove_host(mmc);
free_irq(host->irq, host);
- if (host->gpio_write_protect)
- gpio_free(host->gpio_write_protect);
del_timer_sync(&host->timer);
mvsd_power_down(host);
- iounmap(host->base);
- release_resource(host->res);
- if (!IS_ERR(host->clk)) {
+ if (!IS_ERR(host->clk))
clk_disable_unprepare(host->clk);
- clk_put(host->clk);
- }
+
mmc_free_host(mmc);
}
platform_set_drvdata(pdev, NULL);
^ permalink raw reply related
* [PATCH 07/14] usb: ehci-omap: Instantiate PHY devices if required
From: Roger Quadros @ 2013-01-11 10:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <Pine.LNX.4.44L0.1301101544140.1178-100000@iolanthe.rowland.org>
On 01/10/2013 10:48 PM, Alan Stern wrote:
> On Thu, 10 Jan 2013, Roger Quadros wrote:
>
>> If the OMAP's Host controller is in PHY mode then we instantiate
>> a platform device for the PHY (one for each port in PHY mode) and
>> hold a reference to it so that we can use the usb_phy API, e.g.
>> while suspend/resume.
>>
>> The platform data for the PHY must be supplied in the newly added
>> .phy_config parameter in struct usbhs_omap_platform_data.
>>
>> The end goal is to move the PHY's reset and power handling code
>> out of the ehci-omap driver and into the phy driver.
>
> As mentioned in another thread, I would prefer to have these changes to
> ehci-omap.c made after the driver is converted to the new "ehci-hcd is
> a library" scheme. The patch below does the conversion; it is meant to
> apply on top of the similar patch for ehci-mxc posted recently on the
> linux-usb mailing list.
>
> After this conversion, the omap_ehci_hcd private data structure doesn't
> have to be allocated specifically. It can be handled in the same way
> as the private data structure in the ehci-mxc patch.
>
> I haven't even tried to compile this. Please let me know how it works.
>
Alan,
Thanks for the patch. I've pasted the version that builds and works and
put you as the Author of the patch, hope it is fine.
I could not find the equivalent ehci-mxc implementation though. Any
pointers to that? Thanks.
cheers,
-roger
>From fafa9c787bcf2ff3f46c07c045997614d7a8a417 Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Fri, 11 Jan 2013 12:37:01 +0200
Subject: [PATCH] USB: ehci-omap: Convert to platform driver
Convert ehci-omap into a platform driver and use ehci-hcd
as a library.
CC: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Roger Quadros <rogerq@ti.com>
---
drivers/usb/host/Kconfig | 2 +-
drivers/usb/host/Makefile | 1 +
drivers/usb/host/ehci-hcd.c | 6 +---
drivers/usb/host/ehci-omap.c | 76
+++++++++++++++++++-----------------------
4 files changed, 37 insertions(+), 48 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index d6bb128..432a463 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -155,7 +155,7 @@ config USB_EHCI_MXC
Variation of ARC USB block used in some Freescale chips.
config USB_EHCI_HCD_OMAP
- bool "EHCI support for OMAP3 and later chips"
+ tristate "EHCI support for OMAP3 and later chips"
depends on USB_EHCI_HCD && ARCH_OMAP
default y
---help---
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 1eb4c30..8a8d079 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_PCI) += pci-quirks.o
obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
obj-$(CONFIG_USB_EHCI_HCD_PLATFORM) += ehci-platform.o
+obj-$(CONFIG_USB_EHCI_HCD_OMAP) += ehci-omap.o
obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index c97503b..c44ef1d 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1260,11 +1260,6 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_hcd_sh_driver
#endif
-#ifdef CONFIG_USB_EHCI_HCD_OMAP
-#include "ehci-omap.c"
-#define PLATFORM_DRIVER ehci_hcd_omap_driver
-#endif
-
#ifdef CONFIG_PPC_PS3
#include "ehci-ps3.c"
#define PS3_SYSTEM_BUS_DRIVER ps3_ehci_driver
@@ -1352,6 +1347,7 @@ MODULE_LICENSE ("GPL");
#if !IS_ENABLED(CONFIG_USB_EHCI_PCI) && \
!IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) && \
+ !IS_ENABLED(CONFIG_USB_EHCI_HCD_OMAP) && \
!defined(CONFIG_USB_CHIPIDEA_HOST) && \
!defined(PLATFORM_DRIVER) && \
!defined(PS3_SYSTEM_BUS_DRIVER) && \
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index b96a4bf..6388aa6 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -36,6 +36,9 @@
* - convert to use hwmod and runtime PM
*/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/usb/ulpi.h>
@@ -43,6 +46,10 @@
#include <linux/pm_runtime.h>
#include <linux/gpio.h>
#include <linux/clk.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
+
+#include "ehci.h"
#include <linux/platform_data/usb-omap.h>
@@ -57,9 +64,11 @@
#define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8
#define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0
-/*-------------------------------------------------------------------------*/
+#define DRIVER_DESC "OMAP-EHCI Host Controller driver"
-static const struct hc_driver ehci_omap_hc_driver;
+static const char hcd_name[] = "ehci-omap";
+
+/*-------------------------------------------------------------------------*/
static inline void ehci_write(void __iomem *base, u32 reg, u32 val)
@@ -166,6 +175,12 @@ static void disable_put_regulator(
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
+static struct hc_driver __read_mostly ehci_omap_hc_driver;
+
+static const struct ehci_driver_overrides ehci_omap_overrides
__initdata = {
+ .reset = omap_ehci_init,
+};
+
/**
* ehci_hcd_omap_probe - initialize TI-based HCDs
*
@@ -315,56 +330,33 @@ static struct platform_driver ehci_hcd_omap_driver = {
/*.suspend = ehci_hcd_omap_suspend, */
/*.resume = ehci_hcd_omap_resume, */
.driver = {
- .name = "ehci-omap",
+ .name = hcd_name,
}
};
/*-------------------------------------------------------------------------*/
-static const struct hc_driver ehci_omap_hc_driver = {
- .description = hcd_name,
- .product_desc = "OMAP-EHCI Host Controller",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
-
- /*
- * basic lifecycle operations
- */
- .reset = omap_ehci_init,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
- .endpoint_reset = ehci_endpoint_reset,
+static int __init ehci_omap_init(void)
+{
+ if (usb_disabled())
+ return -ENODEV;
- /*
- * scheduling support
- */
- .get_frame_number = ehci_get_frame,
+ pr_info("%s: " DRIVER_DESC "\n", hcd_name);
- /*
- * root hub support
- */
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
+ ehci_init_driver(&ehci_omap_hc_driver, &ehci_omap_overrides);
+ return platform_driver_register(&ehci_hcd_omap_driver);
+}
+module_init(ehci_omap_init);
- .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
-};
+static void __exit ehci_omap_cleanup(void)
+{
+ platform_driver_unregister(&ehci_hcd_omap_driver);
+}
+module_exit(ehci_omap_cleanup);
MODULE_ALIAS("platform:omap-ehci");
MODULE_AUTHOR("Texas Instruments, Inc.");
MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
--
1.7.4.1
^ permalink raw reply related
* [PATCH 02/16] ARM: b.L: introduce the CPU/cluster power API
From: Will Deacon @ 2013-01-11 10:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1301102055320.6300@xanadu.home>
On Fri, Jan 11, 2013 at 02:30:06AM +0000, Nicolas Pitre wrote:
> On Thu, 10 Jan 2013, Will Deacon wrote:
> > On Thu, Jan 10, 2013 at 12:20:37AM +0000, Nicolas Pitre wrote:
> > > +int bL_cpu_power_up(unsigned int cpu, unsigned int cluster)
> > > +{
> > > + if (!platform_ops)
> > > + return -EUNATCH;
> >
> > Is this the right error code?
>
> It is as good as any other, with some meaning to be distinguished from
> the traditional ones like -ENOMEM or -EINVAL that the platform backends
> could return.
>
> Would you prefer another one?
-ENODEV? Nothing to lose sleep over though.
> > > + might_sleep();
> > > + return platform_ops->power_up(cpu, cluster);
> > > +}
> > > +
> > > +typedef void (*phys_reset_t)(unsigned long);
> >
> > Maybe it's worth putting this typedef in a header file somewhere. It's
> > also used by the soft reboot code.
>
> Agreed. Maybe separately from this series though.
>
> > > +
> > > +void bL_cpu_power_down(void)
> > > +{
> > > + phys_reset_t phys_reset;
> > > +
> > > + BUG_ON(!platform_ops);
> >
> > Seems a bit overkill, or are we unrecoverable by this point?
>
> We are. The upper layer expects this CPU to be dead and there is no
> easy recovery possible. This is a "should never happen" condition, and
> the kernel is badly configured otherwise.
Okey doke, that's what I feared. The BUG_ON makes sense then.
> > > +/*
> > > + * Platform specific methods used in the implementation of the above API.
> > > + */
> > > +struct bL_platform_power_ops {
> > > + int (*power_up)(unsigned int cpu, unsigned int cluster);
> > > + void (*power_down)(void);
> > > + void (*suspend)(u64);
> > > + void (*powered_up)(void);
> > > +};
> >
> > It would be good if these prototypes matched the PSCI code, then platforms
> > could just glue them together directly.
>
> No.
>
> I discussed this at length with Charles (the PSCI spec author) already.
> Even in the PSCI case, a minimum PSCI backend is necessary to do some
> impedance matching between what the PSCI calls expect as arguments and
> what this kernel specific API needs to express. For example, the UP
> method needs to always be provided with the address for bL_entry,
> irrespective of where the user of this kernel API wants execution to be
> resumed. There might be some cases where the backend might decide to
> override the desired power saving state because of other kernel induced
> constraints (ongoing DMA operation for example) that PSCI doesn't (and
> should not) know about. And the best place to arbitrate between those
> platform specific constraints is in this platform specific shim or
> backend.
Yes, you're right. I was thinking we could convert cpu/cluster into cpuid
automatically, but actually it's not guaranteed that the PSCI firmware will
follow the MPIDR format so we even need platform-specific marshalling for
that.
Thanks for the reply,
Will
^ permalink raw reply
* [PATCH 1/1] usb: fsl-mxc-udc: fix build error due to mach/hardware.h
From: Felipe Balbi @ 2013-01-11 10:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1357898188-10540-1-git-send-email-peter.chen@freescale.com>
Hi,
On Fri, Jan 11, 2013 at 05:56:28PM +0800, Peter Chen wrote:
> It changes the driver to use platform_device_id rather than cpu_is_xxx
> to determine the SoC type, and updates the platform code accordingly.
>
> Compile ok at imx_v6_v7_defconfig with CONFIG_USB_FSL_USB2 enable.
> Tested at mx51 bbg board, it works ok after enable phy clock
> (Need another patch to fix this problem)
>
> Signed-off-by: Peter Chen <peter.chen@freescale.com>
this is too big for -rc, can you break it down into smaller pieces ?
--
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130111/ae0495ad/attachment.sig>
^ permalink raw reply
* [PATCH 01/16] ARM: b.L: secondary kernel entry code
From: Will Deacon @ 2013-01-11 10:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1301102006370.6300@xanadu.home>
On Fri, Jan 11, 2013 at 01:26:21AM +0000, Nicolas Pitre wrote:
> On Thu, 10 Jan 2013, Will Deacon wrote:
> > On Thu, Jan 10, 2013 at 12:20:36AM +0000, Nicolas Pitre wrote:
> > > +
> > > +extern volatile unsigned long bL_entry_vectors[BL_NR_CLUSTERS][BL_CPUS_PER_CLUSTER];
> >
> > Does this actually need to be volatile? I'd have thought a compiler
> > barrier in place of the smp_wmb below would be enough (following on from
> > Catalin's comments).
>
> Actually, I did the reverse i.e. I removed the smp_wmb() entirely. A
> compiler barrier forces the whole world to memory while here we only
> want this particular assignment to be pushed out.
>
> Furthermore, I like the volatile as it flags that this is a special
> variable which in this case is also accessed from CPUs with no cache.
Ok, fair enough. Given that the smp_wmb isn't needed that sounds better.
> > > + /* We didn't expect this CPU. Try to make it quiet. */
> > > +1: wfi
> > > + wfe
> > > + b 1b
> >
> > I realise this CPU is stuck at this point, but you should have a dsb
> > before a wfi instruction. This could be problematic with the CCI this
> > early, so maybe just a comment saying that it doesn't matter because we
> > don't care about this core?
>
> Why a dsb? No data was even touched at this point. And since this is
> meant to be a better "b ." kind of loop, I'd rather not try to make it
> more sophisticated than it already is. And of course it is meant to
> never be executed in practice.
Sure, that's why I think just mentioning that we don't ever plan to boot
this CPU is a good idea (so people don't add code here later on).
> > > diff --git a/arch/arm/include/asm/bL_entry.h b/arch/arm/include/asm/bL_entry.h
> > > new file mode 100644
> > > index 0000000000..ff623333a1
> > > --- /dev/null
> > > +++ b/arch/arm/include/asm/bL_entry.h
> > > @@ -0,0 +1,35 @@
> > > +/*
> > > + * arch/arm/include/asm/bL_entry.h
> > > + *
> > > + * Created by: Nicolas Pitre, April 2012
> > > + * Copyright: (C) 2012 Linaro Limited
> > > + *
> > > + * This program is free software; you can redistribute it and/or modify
> > > + * it under the terms of the GNU General Public License version 2 as
> > > + * published by the Free Software Foundation.
> > > + */
> > > +
> > > +#ifndef BL_ENTRY_H
> > > +#define BL_ENTRY_H
> > > +
> > > +#define BL_CPUS_PER_CLUSTER 4
> > > +#define BL_NR_CLUSTERS 2
> >
> > Hmm, I see these have to be constant so you can allocate your space in
> > the assembly file. In which case, I think it's worth changing their
> > names to have MAX or LIMIT in them...
>
> Yes, good point. I'll change them.
Thanks.
> > maybe they could even be CONFIG options?
>
> Nah. I prefer not adding new config options unless this is really
> necessary or useful. For the forseeable future, we'll see systems with
> at most 2 clusters and at most 4 CPUs per cluster. That could easily be
> revisited later if that becomes unsuitable for some new systems.
The current GIC is limited to 8 CPUs, so 4x2 is also a realistic possibility.
> Initially I wanted all those things to be runtime sized in relation with
> the TODO item in the commit log. That too can come later.
Out of interest: how would you achieve that? I also thought about getting
this information from the device tree, but I can't see how to plug that in
with static storage.
Cheers,
Will
^ permalink raw reply
* [PATCH] ARM: ux500: Include the PRCMU's Secure Registers in DB8500's DT
From: Lee Jones @ 2013-01-11 10:43 UTC (permalink / raw)
To: linux-arm-kernel
Currently we only include the PRCMU's primary registers when
referencing the register count in the 'reg' property. This patch
expands that count to include the secure registers also.
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
arch/arm/boot/dts/dbx5x0.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index 2efd9c8..337c3b9 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -190,7 +190,7 @@
prcmu at 80157000 {
compatible = "stericsson,db8500-prcmu";
- reg = <0x80157000 0x1000>;
+ reg = <0x80157000 0x2000>;
interrupts = <0 47 0x4>;
#address-cells = <1>;
#size-cells = <1>;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 03/16] ARM: b.L: introduce helpers for platform coherency exit/setup
From: Dave Martin @ 2013-01-11 10:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1301101713380.6300@xanadu.home>
On Thu, Jan 10, 2013 at 05:31:08PM -0500, Nicolas Pitre wrote:
> On Thu, 10 Jan 2013, Catalin Marinas wrote:
>
> > On 10 January 2013 17:59, Nicolas Pitre <nicolas.pitre@linaro.org> wrote:
> > > On Thu, 10 Jan 2013, Catalin Marinas wrote:
> > >
> > >> On 10 January 2013 00:20, Nicolas Pitre <nicolas.pitre@linaro.org> wrote:
> > >> > --- a/arch/arm/common/bL_entry.c
> > >> > +++ b/arch/arm/common/bL_entry.c
> > >> > @@ -116,3 +116,163 @@ int bL_cpu_powered_up(void)
> > >> > platform_ops->powered_up();
> > >> > return 0;
> > >> > }
> > >> > +
> > >> > +struct bL_sync_struct bL_sync;
> > >> > +
> > >> > +static void __sync_range(volatile void *p, size_t size)
> > >> > +{
> > >> > + char *_p = (char *)p;
> > >> > +
> > >> > + __cpuc_flush_dcache_area(_p, size);
> > >> > + outer_flush_range(__pa(_p), __pa(_p + size));
> > >> > + outer_sync();
> > ...
> > >> However, on the same CPU you can get a speculative load into L1 after
> > >> the L1 flush but before the L2 flush, so the reader case can fail.
> > >>
> > >> The sequence for readers is (note *L2* inval first):
> > >>
> > >> L2 inval
> > >> L1 inval
> > >
> > > As you noted below and as I explained above, this can't be an inval
> > > operation as that could discard a concurrent writer's update.
> > >
> > >> The sequence for writers is:
> > >>
> > >> L1 clean
> > >> L2 clean
> > >>
> > >> The bi-directional sequence (that's what you need) is:
> > >>
> > >> L1 clean
> > >> L2 clean+inval
> > >> L1 clean+inval
Agreed. My bad, sorry... I was focusing on other aspects; plus we have
no actual outer cache, so the mis-ordering is hidden in our testing.
This code has been through a few iterations, some of which had separate
sequences for reads and writes, though possibly the ordering is still
wrong.
If our cache is enabled, we may end up with the responsibility of writing
out another CPU's dirty lines due to speculative migration, so for most
or all of the flushes here, we do need the third sequence (inner clean;
outer clean+invalidate; inner clean+invalidate)
> > >>
> > >> The last L1 op must be clean+inval in case another CPU writes to this
> > >> location to avoid discarding the write.
> > >>
> > >> If you don't have an L2, you just end up with two L1 clean ops, so you
> > >> can probably put some checks.
> > >
> > > In fact, since this is only used on A7/A15 right now, there is no outer
> > > cache and the outer calls are effectively no-ops. I'm wondering if
> > > those should simply be removed until/unless there is some system showing
> > > up with a need for them.
> >
> > You could. I expect multi-cluster systems to have integrated L2 cache
> > and avoid explicit outer cache maintenance. But is there a chance that
> > your patches could be generalised to existing systems with A9 (not b.L
> > configuration but just hotplug or cpuidle support)? I haven't finished
> > reading all the patches, so maybe that's not the case at all.
>
> I suppose it could, although the special requirements put on the first
> man / last man exist only for multi-cluster systems. OTOH, existing A9
> systems are already served by far less complex code already, so it is
> really a matter of figuring out if the backend for those A9 systems
> needed by this cluster code would be simpler than the existing code, in
> which case that would certainly be beneficial.
The outer operations just expand to nothing if there is no outer cache; the
optimisation would be that instead of L1 clean; L1 clean+inval, we just
need L1 clean+inval.
> > Anyway, my point is that if L1 is inner and L2 outer, the correct
> > bi-derectional flushing sequence is slightly different.
>
> Agreed, I'll make sure to capture that in the code somehow.
I'll have a go at this today (but I won't over-elaborate in case you've
already done it...)
Cheers
---Dave
^ permalink raw reply
* Question:add
From: Steve zhan @ 2013-01-11 10:24 UTC (permalink / raw)
To: linux-arm-kernel
All:
I have find that arm gic driver have not register irq_disable
method, as below:
static struct irq_chip gic_chip = {
.name = "GIC",
.irq_mask = gic_mask_irq,
.irq_unmask = gic_unmask_irq,
.irq_eoi = gic_eoi_irq,
.irq_set_type = gic_set_type,
.irq_retrigger = gic_retrigger,
#ifdef CONFIG_SMP
.irq_set_affinity = gic_set_affinity,
#endif
.irq_set_wake = gic_set_wake,
};
Question is:
When some drivers want to disable irq, maybe it will call
linux standard inerface: irq_disable() that defined in include\
linux\interrupt.h, this function will call
void irq_disable(struct irq_desc *desc)
{
irq_state_set_disabled(desc);
if (desc->irq_data.chip->irq_disable) {
desc->irq_data.chip->irq_disable(&desc->irq_data);
irq_state_set_masked(desc);
}
}
Because gic have not register irq_diable method, so the interrupt can
not disable immediately, it is enable until the interrupt come next time,
then disalbed by mask because irq_state_set_disable(desc);
I have checked irq_enable method:
void irq_enable(struct irq_desc *desc)
{
irq_state_clr_disabled(desc);
if (desc->irq_data.chip->irq_enable)
desc->irq_data.chip->irq_enable(&desc->irq_data);
else
desc->irq_data.chip->irq_unmask(&desc->irq_data);
irq_state_clr_masked(desc);
}
This method have do unmask when irq_enable method is not exist.
Is it a good idea to add irq_mask call in irq_disable()?
Regards,
Steve
^ permalink raw reply
* [v2 3/9] ARM: tegra: # of CPU cores detection w/ & w/o HAVE_ARM_SCU
From: Lorenzo Pieralisi @ 2013-01-11 10:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50EEF235.7070200@wwwdotorg.org>
On Thu, Jan 10, 2013 at 04:54:13PM +0000, Stephen Warren wrote:
> On 01/10/2013 05:58 AM, Hiroshi Doyu wrote:
> > Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> wrote @ Wed, 9 Jan 2013 16:17:00 +0100:
> ...
> > With your "[PATCH] ARM: kernel: DT cpu map validity check helper
> > function", my original patch gets as below. I think that the following
> > "smp_detect_ncores()" function may be so generic that it could be
> > moved in some common place than platform?
> >
> > From f5f2a43952ce75fe061b3808b994c3ceb07f1af1 Mon Sep 17 00:00:00 2001
> > From: Hiroshi Doyu <hdoyu@nvidia.com>
> > Date: Mon, 26 Nov 2012 12:25:14 +0200
> > Subject: [PATCH 1/1] ARM: tegra: # of CPU cores detection w/ & w/o
> > HAVE_ARM_SCU
> >
> > The method to detect the number of CPU cores on Cortex-A9 MPCore and
> > Cortex-A15 MPCore is different. On Cortex-A9 MPCore we can get this
> > information from the Snoop Control Unit(SCU). On Cortex-A15 MPCore we
> > have to read it from the system coprocessor(CP15), because the SCU on
> > Cortex-A15 MPCore does not have software readable registers. This
> > patch selects the correct method at runtime based on the CPU ID.
>
> > diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
>
> > +static int __init smp_detect_ncores(void)
> > +{
> > + unsigned int ncores, mpidr;
> > + u32 l2ctlr;
> > + phys_addr_t pa;
> > +
> > + mpidr = read_cpuid_mpidr();
> > + switch (mpidr) {
> > + case ARM_CPU_PART_CORTEX_A15:
> > + asm("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr));
> > + ncores = ((l2ctlr >> 24) & 3) + 1;
> > + break;
> > + case ARM_CPU_PART_CORTEX_A9:
> > + /* Get SCU physical base */
> > + asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (pa));
> > + scu_base = IO_ADDRESS(pa);
> > + ncores = scu_get_core_count(scu_base);
> > + break;
> > + default:
> > + pr_warn("Unsupported mpidr\n");
> > + ncores = 1;
> > + break;
> > + }
> > +
> > + return ncores;
> > +}
>
> Why not just remove that function...
>
> > /*
> > * Initialise the CPU possible map early - this describes the CPUs
> > * which may be present or become present in the system.
> > */
> > static void __init tegra_smp_init_cpus(void)
> > {
> > - unsigned int i, ncores = scu_get_core_count(scu_base);
> > -
> > - if (ncores > nr_cpu_ids) {
> > - pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
> > - ncores, nr_cpu_ids);
> > - ncores = nr_cpu_ids;
> > + if (!arm_dt_cpu_map_valid()) {
> > + unsigned int i, ncores;
> > +
> > + ncores = smp_detect_ncores();
>
> And just say "ncores = 1" here?
>
> For Tegra, it's trivial to simply put the patch adding the required DT
> nodes before this patch, and then there's no need for any
> backwards-compatibility, since the nodes are guaranteed to be there.
If you are willing to accept that your code proposal is perfectly fine by me.
Thanks,
Lorenzo
^ permalink raw reply
* [PATCH] ARM: call disable_nonboot_cpus() from machine_shutdown()
From: Russell King - ARM Linux @ 2013-01-11 10:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87d2xcfeew.fsf@xmission.com>
On Thu, Jan 10, 2013 at 09:59:35PM -0800, Eric W. Biederman wrote:
> Russell King - ARM Linux <linux@arm.linux.org.uk> writes:
>
> > On Sun, Jan 06, 2013 at 05:53:30PM -0800, Eric W. Biederman wrote:
> >> I have cleaned up the mess that is the reboot path once a bunch of years
> >> ago, and apparently it is deteriorating again.
> >
> > Unfortunately, that's what happens when lots of cooks get their fingers
> > in a pie with no coordination. This is why having maintainers is soo
> > important for code - a good maintainer ensures that the code remains
> > high quality by whatever means.
> >
> > Code without maintainers is subject to modification in all kinds of
> > random ways, including duplicating code amongst architectures which
> > should be generic code - that happens because no one wants to understand
> > what other architectures require.
>
> I don't think you meant to but I have been rather strongly insulted.
Why would you be insulted by the above? It's a statement of fact that
is true for anything. Ever heard of the expression "Too many cooks
spoil the broth" ? Does that expression insult you too?
You've admitted that you don't have time to look at the shutdown/reboot
paths very much, so they are by way of that fact lacking in maintainer
input - but if you read the rest of what I wrote, I also commented that
they were still in pretty good shape inspite of that.
So actually, there's a complement there. Shame you missed it.
> Now sometimes_dangerously_hotunplug_all_but_one_cpu() on the reboot path
> was added just a few months ago in Oct 2012, and it appears to due to
> weird ARM maintainership.
Err. No. Stop trying to accuse people of being crap when there's no
evidence:
commit f96972f2dc6365421cf2366ebd61ee4cf060c8d5
Author: Shawn Guo <shawn.guo@linaro.org>
Date: Thu Oct 4 17:12:23 2012 -0700
kernel/sys.c: call disable_nonboot_cpus() in kernel_restart()
...
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
No ARM maintainers were involved in that change. I just checked my
mailboxes for September 2012 which is when it was mailed to the list.
It got missed, and Andrew replied and accepted the patch (as is
illustrated by the sign-offs). And even if _I_ had been involved with
it, _I_ would not have spotted the x86 behaviour, just the same that
Andrew didn't.
Is this not itself evidence of my comment above: had the above change
gone through someone who had a deep understanding of that code - iow,
a maintainer, it probably would not have been committed to the kernel?
To accuse others who have nothing to do with the area, and weren't
involved with the change in any way of being responsible for that
change is... well... I don't think there's anything that can be said
to that which isn't inflamatory.
It seems that, given your comments, the above commit needs to be reverted,
and then _maybe_ the disable_nonboot_cpus() call should be added to ARMs
machine_shutdown() instead.
^ permalink raw reply
* [PATCH] ARM: kernel: DT cpu map validity check helper function
From: Lorenzo Pieralisi @ 2013-01-11 10:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1301101115350.6300@xanadu.home>
On Thu, Jan 10, 2013 at 04:16:43PM +0000, Nicolas Pitre wrote:
> On Thu, 10 Jan 2013, Lorenzo Pieralisi wrote:
>
> > On Thu, Jan 10, 2013 at 12:15:14PM +0000, Dave Martin wrote:
> > > On Thu, Jan 10, 2013 at 11:48:27AM +0000, Lorenzo Pieralisi wrote:
> > > > Since the introduction of /cpu nodes bindings for ARM and the
> > > > corresponding parse function arm_dt_init_cpu_maps(), the cpu_logical_map
> > > > and the number of possible CPUs are set according to the DT /cpu
> > > > nodes entries. Currently most of the existing ARM SMP platforms detect the
> > > > number of cores through HW probing in their .smp_init_cpus functions and set
> > > > the possible CPU mask accordingly.
> > > > This method should be upgraded so that the CPU counting mechanism will be
> > > > based on DT, keeping legacy HW probing mechanism as a fall back solution.
> > > >
> > > > In order to implement this fall back solution mechanism, the ARM DT code
> > > > should provide a helper function to platforms to check if the cpu map
> > > > has been properly initialized through DT. If the check fails the
> > > > platform will resort to legacy HW based cores counting mechanism.
> > > >
> > > > This patch implements a trivial flag and a helper function that platform
> > > > can call to check whether DT based cpu map initialization and cores count
> > > > were completed successfully.
> > > >
> > > > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > > > ---
> > > > arch/arm/include/asm/prom.h | 10 ++++++++++
> > > > arch/arm/kernel/devtree.c | 5 +++++
> > > > 2 files changed, 15 insertions(+)
> > > >
> > > > diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h
> > > > index a219227..487614a 100644
> > > > --- a/arch/arm/include/asm/prom.h
> > > > +++ b/arch/arm/include/asm/prom.h
> > > > @@ -18,6 +18,15 @@
> > > > extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
> > > > extern void arm_dt_memblock_reserve(void);
> > > > extern void __init arm_dt_init_cpu_maps(void);
> > > > +/*
> > > > + * Return true if cpu map initialization has been
> > > > + * carried out correctly from DT
> > > > + */
> > > > +static inline bool __init arm_dt_cpu_map_valid(void)
> > > > +{
> > > > + extern bool valid_dt_cpu_map;
> > > > + return valid_dt_cpu_map;
> > > > +}
> > > >
> > > > #else /* CONFIG_OF */
> > > >
> > > > @@ -28,6 +37,7 @@ static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys)
> > > >
> > > > static inline void arm_dt_memblock_reserve(void) { }
> > > > static inline void arm_dt_init_cpu_maps(void) { }
> > > > +static inline bool __init arm_dt_cpu_map_valid(void) { return false; }
> > > >
> > > > #endif /* CONFIG_OF */
> > > > #endif /* ASMARM_PROM_H */
> > > > diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
> > > > index 70f1bde..c82af3b 100644
> > > > --- a/arch/arm/kernel/devtree.c
> > > > +++ b/arch/arm/kernel/devtree.c
> > > > @@ -62,6 +62,10 @@ void __init arm_dt_memblock_reserve(void)
> > > > memblock_reserve(base, size);
> > > > }
> > > > }
> > > > +/*
> > > > + * Export DT cpu map validity flag to platforms
> > > > + */
> > > > +bool valid_dt_cpu_map __initdata;
> > >
> > > Is there any possibility of this being useful after boot?
> > > Hopefully not, but maybe there's something I haven't considered.
> >
> > I do not think so, at least for the use cases I have envisaged at the moment,
> > but it is certainly something I should consider.
>
> Let's simply adjust the code in the future if that ever becomes the
> case.
I will check against cpu_possible_mask, that will solve the problem and
avoid this niggle.
Thanks,
Lorenzo
^ permalink raw reply
* [PATCH] ARM: kernel: DT cpu map validity check helper function
From: Lorenzo Pieralisi @ 2013-01-11 9:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50EEEF97.4000700@gmail.com>
On Thu, Jan 10, 2013 at 04:43:03PM +0000, Rob Herring wrote:
>
>
> On 01/10/2013 05:48 AM, Lorenzo Pieralisi wrote:
> > Since the introduction of /cpu nodes bindings for ARM and the
> > corresponding parse function arm_dt_init_cpu_maps(), the cpu_logical_map
> > and the number of possible CPUs are set according to the DT /cpu
> > nodes entries. Currently most of the existing ARM SMP platforms detect the
> > number of cores through HW probing in their .smp_init_cpus functions and set
> > the possible CPU mask accordingly.
> > This method should be upgraded so that the CPU counting mechanism will be
> > based on DT, keeping legacy HW probing mechanism as a fall back solution.
> >
> > In order to implement this fall back solution mechanism, the ARM DT code
> > should provide a helper function to platforms to check if the cpu map
> > has been properly initialized through DT. If the check fails the
> > platform will resort to legacy HW based cores counting mechanism.
> >
> > This patch implements a trivial flag and a helper function that platform
> > can call to check whether DT based cpu map initialization and cores count
> > were completed successfully.
> >
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > ---
> > arch/arm/include/asm/prom.h | 10 ++++++++++
> > arch/arm/kernel/devtree.c | 5 +++++
> > 2 files changed, 15 insertions(+)
> >
> > diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h
> > index a219227..487614a 100644
> > --- a/arch/arm/include/asm/prom.h
> > +++ b/arch/arm/include/asm/prom.h
> > @@ -18,6 +18,15 @@
> > extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
> > extern void arm_dt_memblock_reserve(void);
> > extern void __init arm_dt_init_cpu_maps(void);
> > +/*
> > + * Return true if cpu map initialization has been
> > + * carried out correctly from DT
> > + */
> > +static inline bool __init arm_dt_cpu_map_valid(void)
> > +{
> > + extern bool valid_dt_cpu_map;
> > + return valid_dt_cpu_map;
> > +}
> >
> > #else /* CONFIG_OF */
> >
> > @@ -28,6 +37,7 @@ static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys)
> >
> > static inline void arm_dt_memblock_reserve(void) { }
> > static inline void arm_dt_init_cpu_maps(void) { }
> > +static inline bool __init arm_dt_cpu_map_valid(void) { return false; }
> >
> > #endif /* CONFIG_OF */
> > #endif /* ASMARM_PROM_H */
> > diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
> > index 70f1bde..c82af3b 100644
> > --- a/arch/arm/kernel/devtree.c
> > +++ b/arch/arm/kernel/devtree.c
> > @@ -62,6 +62,10 @@ void __init arm_dt_memblock_reserve(void)
> > memblock_reserve(base, size);
> > }
> > }
> > +/*
> > + * Export DT cpu map validity flag to platforms
> > + */
> > +bool valid_dt_cpu_map __initdata;
> >
> > /*
> > * arm_dt_init_cpu_maps - Function retrieves cpu nodes from the device tree
> > @@ -158,6 +162,7 @@ void __init arm_dt_init_cpu_maps(void)
> > * a reg property, the DT CPU list can be considered valid and the
> > * logical map created in smp_setup_processor_id() can be overridden
> > */
> > + valid_dt_cpu_map = true;
> > for (i = 0; i < cpuidx; i++) {
> > set_cpu_possible(i, true);
>
> I don't see why we need another variable. Doesn't cpu_possible mask
> being set here imply that the DT map is valid.
Yes, that's correct I can use cpu_possible mask to check that, but I still
want to do it through a function/macro, I do not want platform code to
check possible mask explicitly, they have to do it through a helper function.
I will remove the variable.
> We should start requiring valid /cpus nodes and the legacy fall-back
> should be temporary.
I could not agree more.
Thanks,
Lorenzo
^ permalink raw reply
* [PATCH 1/1] usb: fsl-mxc-udc: fix build error due to mach/hardware.h
From: Peter Chen @ 2013-01-11 9:56 UTC (permalink / raw)
To: linux-arm-kernel
It changes the driver to use platform_device_id rather than cpu_is_xxx
to determine the SoC type, and updates the platform code accordingly.
Compile ok at imx_v6_v7_defconfig with CONFIG_USB_FSL_USB2 enable.
Tested at mx51 bbg board, it works ok after enable phy clock
(Need another patch to fix this problem)
Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
arch/arm/mach-imx/clk-imx25.c | 6 +-
arch/arm/mach-imx/clk-imx27.c | 6 +-
arch/arm/mach-imx/clk-imx31.c | 6 +-
arch/arm/mach-imx/clk-imx35.c | 6 +-
arch/arm/mach-imx/clk-imx51-imx53.c | 6 +-
arch/arm/mach-imx/devices/devices-common.h | 1 +
arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c | 15 +++---
drivers/usb/gadget/fsl_mxc_udc.c | 17 +++----
drivers/usb/gadget/fsl_udc_core.c | 52 +++++++++++++-------
drivers/usb/gadget/fsl_usb2_udc.h | 13 ++++--
include/linux/fsl_devices.h | 8 +++
11 files changed, 82 insertions(+), 54 deletions(-)
diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c
index b197aa7..67e353d 100644
--- a/arch/arm/mach-imx/clk-imx25.c
+++ b/arch/arm/mach-imx/clk-imx25.c
@@ -254,9 +254,9 @@ int __init mx25_clocks_init(void)
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
clk_register_clkdev(clk[usbotg_ahb], "ahb", "mxc-ehci.2");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
- clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
- clk_register_clkdev(clk[usbotg_ahb], "ahb", "fsl-usb2-udc");
- clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
+ clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx25");
+ clk_register_clkdev(clk[usbotg_ahb], "ahb", "imx-udc-mx25");
+ clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx25");
clk_register_clkdev(clk[nfc_ipg_per], NULL, "imx25-nand.0");
/* i.mx25 has the i.mx35 type cspi */
clk_register_clkdev(clk[cspi1_ipg], NULL, "imx35-cspi.0");
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
index 4c1d1e4..1ffe3b5 100644
--- a/arch/arm/mach-imx/clk-imx27.c
+++ b/arch/arm/mach-imx/clk-imx27.c
@@ -236,9 +236,9 @@ int __init mx27_clocks_init(unsigned long fref)
clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx21-fb.0");
clk_register_clkdev(clk[csi_ahb_gate], "ahb", "imx27-camera.0");
clk_register_clkdev(clk[per4_gate], "per", "imx27-camera.0");
- clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
- clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc");
- clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc");
+ clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx27");
+ clk_register_clkdev(clk[usb_ipg_gate], "ipg", "imx-udc-mx27");
+ clk_register_clkdev(clk[usb_ahb_gate], "ahb", "imx-udc-mx27");
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0");
clk_register_clkdev(clk[usb_ipg_gate], "ipg", "mxc-ehci.0");
clk_register_clkdev(clk[usb_ahb_gate], "ahb", "mxc-ehci.0");
diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c
index 8be64e0..ef66eaf 100644
--- a/arch/arm/mach-imx/clk-imx31.c
+++ b/arch/arm/mach-imx/clk-imx31.c
@@ -139,9 +139,9 @@ int __init mx31_clocks_init(unsigned long fref)
clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.2");
clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.2");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
- clk_register_clkdev(clk[usb_div_post], "per", "fsl-usb2-udc");
- clk_register_clkdev(clk[usb_gate], "ahb", "fsl-usb2-udc");
- clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
+ clk_register_clkdev(clk[usb_div_post], "per", "imx-udc-mx31");
+ clk_register_clkdev(clk[usb_gate], "ahb", "imx-udc-mx31");
+ clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx31");
clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
/* i.mx31 has the i.mx21 type uart */
clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c
index 66f3d65..69fe9c8 100644
--- a/arch/arm/mach-imx/clk-imx35.c
+++ b/arch/arm/mach-imx/clk-imx35.c
@@ -251,9 +251,9 @@ int __init mx35_clocks_init()
clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2");
clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2");
clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.2");
- clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
- clk_register_clkdev(clk[ipg], "ipg", "fsl-usb2-udc");
- clk_register_clkdev(clk[usbotg_gate], "ahb", "fsl-usb2-udc");
+ clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx35");
+ clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx35");
+ clk_register_clkdev(clk[usbotg_gate], "ahb", "imx-udc-mx35");
clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0");
clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0");
clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
index 579023f..fb7cb84 100644
--- a/arch/arm/mach-imx/clk-imx51-imx53.c
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -269,9 +269,9 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
clk_register_clkdev(clk[usboh3_per_gate], "per", "mxc-ehci.2");
clk_register_clkdev(clk[usboh3_gate], "ipg", "mxc-ehci.2");
clk_register_clkdev(clk[usboh3_gate], "ahb", "mxc-ehci.2");
- clk_register_clkdev(clk[usboh3_per_gate], "per", "fsl-usb2-udc");
- clk_register_clkdev(clk[usboh3_gate], "ipg", "fsl-usb2-udc");
- clk_register_clkdev(clk[usboh3_gate], "ahb", "fsl-usb2-udc");
+ clk_register_clkdev(clk[usboh3_per_gate], "per", "imx-udc-mx51");
+ clk_register_clkdev(clk[usboh3_gate], "ipg", "imx-udc-mx51");
+ clk_register_clkdev(clk[usboh3_gate], "ahb", "imx-udc-mx51");
clk_register_clkdev(clk[nfc_gate], NULL, "imx51-nand");
clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "imx-ssi.0");
clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "imx-ssi.1");
diff --git a/arch/arm/mach-imx/devices/devices-common.h b/arch/arm/mach-imx/devices/devices-common.h
index 6277baf..9bd5777 100644
--- a/arch/arm/mach-imx/devices/devices-common.h
+++ b/arch/arm/mach-imx/devices/devices-common.h
@@ -63,6 +63,7 @@ struct platform_device *__init imx_add_flexcan(
#include <linux/fsl_devices.h>
struct imx_fsl_usb2_udc_data {
+ const char *devid;
resource_size_t iobase;
resource_size_t irq;
};
diff --git a/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c b/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c
index 37e4439..fb527c7 100644
--- a/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c
+++ b/arch/arm/mach-imx/devices/platform-fsl-usb2-udc.c
@@ -11,35 +11,36 @@
#include "../hardware.h"
#include "devices-common.h"
-#define imx_fsl_usb2_udc_data_entry_single(soc) \
+#define imx_fsl_usb2_udc_data_entry_single(soc, _devid) \
{ \
+ .devid = _devid, \
.iobase = soc ## _USB_OTG_BASE_ADDR, \
.irq = soc ## _INT_USB_OTG, \
}
#ifdef CONFIG_SOC_IMX25
const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data __initconst =
- imx_fsl_usb2_udc_data_entry_single(MX25);
+ imx_fsl_usb2_udc_data_entry_single(MX25, "imx-udc-mx25");
#endif /* ifdef CONFIG_SOC_IMX25 */
#ifdef CONFIG_SOC_IMX27
const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data __initconst =
- imx_fsl_usb2_udc_data_entry_single(MX27);
+ imx_fsl_usb2_udc_data_entry_single(MX27, "imx-udc-mx27");
#endif /* ifdef CONFIG_SOC_IMX27 */
#ifdef CONFIG_SOC_IMX31
const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data __initconst =
- imx_fsl_usb2_udc_data_entry_single(MX31);
+ imx_fsl_usb2_udc_data_entry_single(MX31, "imx-udc-mx31");
#endif /* ifdef CONFIG_SOC_IMX31 */
#ifdef CONFIG_SOC_IMX35
const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data __initconst =
- imx_fsl_usb2_udc_data_entry_single(MX35);
+ imx_fsl_usb2_udc_data_entry_single(MX35, "imx-udc-mx35");
#endif /* ifdef CONFIG_SOC_IMX35 */
#ifdef CONFIG_SOC_IMX51
const struct imx_fsl_usb2_udc_data imx51_fsl_usb2_udc_data __initconst =
- imx_fsl_usb2_udc_data_entry_single(MX51);
+ imx_fsl_usb2_udc_data_entry_single(MX51, "imx-udc-mx51");
#endif
struct platform_device *__init imx_add_fsl_usb2_udc(
@@ -57,7 +58,7 @@ struct platform_device *__init imx_add_fsl_usb2_udc(
.flags = IORESOURCE_IRQ,
},
};
- return imx_add_platform_device_dmamask("fsl-usb2-udc", -1,
+ return imx_add_platform_device_dmamask(data->devid, -1,
res, ARRAY_SIZE(res),
pdata, sizeof(*pdata), DMA_BIT_MASK(32));
}
diff --git a/drivers/usb/gadget/fsl_mxc_udc.c b/drivers/usb/gadget/fsl_mxc_udc.c
index 1b0f086..f313085 100644
--- a/drivers/usb/gadget/fsl_mxc_udc.c
+++ b/drivers/usb/gadget/fsl_mxc_udc.c
@@ -18,8 +18,6 @@
#include <linux/platform_device.h>
#include <linux/io.h>
-#include <mach/hardware.h>
-
static struct clk *mxc_ahb_clk;
static struct clk *mxc_per_clk;
static struct clk *mxc_ipg_clk;
@@ -28,7 +26,7 @@ static struct clk *mxc_ipg_clk;
#define USBPHYCTRL_OTGBASE_OFFSET 0x608
#define USBPHYCTRL_EVDO (1 << 23)
-int fsl_udc_clk_init(struct platform_device *pdev)
+int fsl_udc_clk_init(enum fsl_udc_type devtype, struct platform_device *pdev)
{
struct fsl_usb2_platform_data *pdata;
unsigned long freq;
@@ -59,7 +57,7 @@ int fsl_udc_clk_init(struct platform_device *pdev)
clk_prepare_enable(mxc_per_clk);
/* make sure USB_CLK is running@60 MHz +/- 1000 Hz */
- if (!cpu_is_mx51()) {
+ if (!(devtype == IMX51_UDC)) {
freq = clk_get_rate(mxc_per_clk);
if (pdata->phy_mode != FSL_USB2_PHY_ULPI &&
(freq < 59999000 || freq > 60001000)) {
@@ -79,19 +77,18 @@ eclkrate:
return ret;
}
-void fsl_udc_clk_finalize(struct platform_device *pdev)
+void fsl_udc_clk_finalize(enum fsl_udc_type devtype,
+ struct platform_device *pdev)
{
struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
- if (cpu_is_mx35()) {
+ if (devtype == IMX35_UDC) {
unsigned int v;
/* workaround ENGcm09152 for i.MX35 */
if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) {
- v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
- USBPHYCTRL_OTGBASE_OFFSET));
+ v = readl(pdata->regs + USBPHYCTRL_OTGBASE_OFFSET);
writel(v | USBPHYCTRL_EVDO,
- MX35_IO_ADDRESS(MX35_USB_BASE_ADDR +
- USBPHYCTRL_OTGBASE_OFFSET));
+ pdata->regs + USBPHYCTRL_OTGBASE_OFFSET);
}
}
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index c19f7f1..9f9005b 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -41,6 +41,7 @@
#include <linux/fsl_devices.h>
#include <linux/dmapool.h>
#include <linux/delay.h>
+#include <linux/of_device.h>
#include <asm/byteorder.h>
#include <asm/io.h>
@@ -2438,17 +2439,13 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
unsigned int i;
u32 dccparams;
- if (strcmp(pdev->name, driver_name)) {
- VDBG("Wrong device");
- return -ENODEV;
- }
-
udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL);
if (udc_controller == NULL) {
ERR("malloc udc failed\n");
return -ENOMEM;
}
+ udc_controller->devtype = pdev->id_entry->driver_data;
pdata = pdev->dev.platform_data;
udc_controller->pdata = pdata;
spin_lock_init(&udc_controller->lock);
@@ -2505,7 +2502,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
#endif
/* Initialize USB clocks */
- ret = fsl_udc_clk_init(pdev);
+ ret = fsl_udc_clk_init(udc_controller->devtype, pdev);
if (ret < 0)
goto err_iounmap_noclk;
@@ -2547,7 +2544,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
dr_controller_setup(udc_controller);
}
- fsl_udc_clk_finalize(pdev);
+ fsl_udc_clk_finalize(udc_controller->devtype, pdev);
/* Setup gadget structure */
udc_controller->gadget.ops = &fsl_gadget_ops;
@@ -2756,22 +2753,41 @@ static int fsl_udc_otg_resume(struct device *dev)
return fsl_udc_resume(NULL);
}
-
/*-------------------------------------------------------------------------
Register entry point for the peripheral controller driver
--------------------------------------------------------------------------*/
-
+static struct platform_device_id fsl_udc_devtype[] = {
+ {
+ .name = "imx-udc-mx25",
+ .driver_data = IMX25_UDC,
+ }, {
+ .name = "imx-udc-mx27",
+ .driver_data = IMX27_UDC,
+ }, {
+ .name = "imx-udc-mx31",
+ .driver_data = IMX31_UDC,
+ }, {
+ .name = "imx-udc-mx35",
+ .driver_data = IMX35_UDC,
+ }, {
+ .name = "imx-udc-mx51",
+ .driver_data = IMX51_UDC,
+ }
+};
+MODULE_DEVICE_TABLE(platform, fsl_udc_devtype);
static struct platform_driver udc_driver = {
- .remove = __exit_p(fsl_udc_remove),
+ .remove = __exit_p(fsl_udc_remove),
+ /* Just for FSL i.mx SoC currently */
+ .id_table = fsl_udc_devtype,
/* these suspend and resume are not usb suspend and resume */
- .suspend = fsl_udc_suspend,
- .resume = fsl_udc_resume,
- .driver = {
- .name = (char *)driver_name,
- .owner = THIS_MODULE,
- /* udc suspend/resume called from OTG driver */
- .suspend = fsl_udc_otg_suspend,
- .resume = fsl_udc_otg_resume,
+ .suspend = fsl_udc_suspend,
+ .resume = fsl_udc_resume,
+ .driver = {
+ .name = (char *)driver_name,
+ .owner = THIS_MODULE,
+ /* udc suspend/resume called from OTG driver */
+ .suspend = fsl_udc_otg_suspend,
+ .resume = fsl_udc_otg_resume,
},
};
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h
index f61a967..bc1f6d0 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/fsl_usb2_udc.h
@@ -505,6 +505,8 @@ struct fsl_udc {
u32 ep0_dir; /* Endpoint zero direction: can be
USB_DIR_IN or USB_DIR_OUT */
u8 device_address; /* Device USB address */
+ /* devtype for kinds of SoC, only i.mx uses it now */
+ enum fsl_udc_type devtype;
};
/*-------------------------------------------------------------------------*/
@@ -591,15 +593,18 @@ static inline struct ep_queue_head *get_qh_by_ep(struct fsl_ep *ep)
struct platform_device;
#ifdef CONFIG_ARCH_MXC
-int fsl_udc_clk_init(struct platform_device *pdev);
-void fsl_udc_clk_finalize(struct platform_device *pdev);
+int fsl_udc_clk_init(enum fsl_udc_type devtype, struct platform_device *pdev);
+void fsl_udc_clk_finalize(enum fsl_udc_type devtype,
+ struct platform_device *pdev);
void fsl_udc_clk_release(void);
#else
-static inline int fsl_udc_clk_init(struct platform_device *pdev)
+static inline int fsl_udc_clk_init(enum fsl_udc_type devtype,
+ struct platform_device *pdev)
{
return 0;
}
-static inline void fsl_udc_clk_finalize(struct platform_device *pdev)
+static inline void fsl_udc_clk_finalize(enum fsl_udc_type devtype,
+ struct platform_device *pdev)
{
}
static inline void fsl_udc_clk_release(void)
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index a82296a..7cb3fe0 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -66,6 +66,14 @@ enum fsl_usb2_phy_modes {
FSL_USB2_PHY_SERIAL,
};
+enum fsl_udc_type {
+ IMX25_UDC,
+ IMX27_UDC,
+ IMX31_UDC,
+ IMX35_UDC,
+ IMX51_UDC,
+};
+
struct clk;
struct platform_device;
--
1.7.0.4
^ permalink raw reply related
* [PATCH] usb: phy: samsung: Add support to set pmu isolation
From: Vivek Gautam @ 2013-01-11 9:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50EFD9B3.7090503@samsung.com>
Hi Sylwester,
On Fri, Jan 11, 2013 at 2:51 PM, Sylwester Nawrocki
<s.nawrocki@samsung.com> wrote:
> On 01/11/2013 09:08 AM, Vivek Gautam wrote:
>> Adding support to parse device node data in order to get
>> required properties to set pmu isolation for usb-phy.
>>
>> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
>
> Thanks for addressing my all comments,
>
> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
>
Thanks for the review and help. :-)
--
Thanks & Regards
Vivek
^ permalink raw reply
* [PATCH v4 1/4] rtc: OMAP: Add system pm_power_off to rtc driver
From: AnilKumar, Chimata @ 2013-01-11 9:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CA+Bv8XaZzWindjhYnXLaqq5mJ6X0Hq=C7NUxW3aK3eh-d6ghtg@mail.gmail.com>
On Fri, Jan 11, 2013 at 15:00:03, AnilKumar, Chimata wrote:
> On Fri, Jan 11, 2013 at 14:24:46, Russ Dill wrote:
> > On Fri, Jan 11, 2013 at 12:08 AM, Russ Dill <russ.dill@gmail.com> wrote:
> > > On Thu, Dec 13, 2012 at 10:03 PM, AnilKumar Ch <anilkumar@ti.com> wrote:
> > >> From: Colin Foe-Parker <colin.foeparker@logicpd.com>
> > >>
> > >> Add system power off control to rtc driver which is the in-charge
> > >> of controlling the BeagleBone system power. The power_off routine
> > >> can be hooked up to "pm_power_off" system call.
> > >>
> > >> System power off sequence:-
> > >> * Set PMIC STATUS_OFF when PMIC_POWER_EN is pulled low
> > >> * Enable PMIC_POWER_EN in rtc module
> > >> * Set rtc ALARM2 time
> > >> * Enable ALARM2 interrupt
> > >>
> > >> Signed-off-by: Colin Foe-Parker <colin.foeparker@logicpd.com>
> > >> [anilkumar at ti.com: move poweroff additions to rtc driver]
> > >> Signed-off-by: AnilKumar Ch <anilkumar@ti.com>
> > >
> > > Looks good
> > >
> > > Reviewed-by: Russ Dill <russ.dill@ti.com>
> > > Acked-by: Russ Dill <russ.dill@ti.com>
> >
> > Sorry, actually, small follow up. Is there any reason this uses
> > readl/writel in some places rather than rtc_read/rtc_write?
>
> Hi Russ Dill,
>
> Thanks for the review
>
> At OMAP_RTC_PMIC_POWER_EN_EN, 32-bit value needs to modified so
> readl/writel are used. While enabling the INTERRUPTS we can change
> it to rtc_read/rtc_write but I am not seeing any advantage if we
> do that apart from consistency.
And driver has to clean-up properly to make use of rtc_read/write
APIs with proper read/write's based on the memory type. Ideally
rtc_readb/w/l and rtc_writeb/w/l should go way from the driver.
This clean-up can be done while converting the driver with platform
specific rtc_read/write.
Thanks
AnilKumar
> > >> ---
> > >> Documentation/devicetree/bindings/rtc/rtc-omap.txt | 5 ++
> > >> drivers/rtc/rtc-omap.c | 74 +++++++++++++++++++-
> > >> 2 files changed, 78 insertions(+), 1 deletion(-)
> > >>
> > >> diff --git a/Documentation/devicetree/bindings/rtc/rtc-omap.txt b/Documentation/devicetree/bindings/rtc/rtc-omap.txt
> > >> index b47aa41..8d9f4f9 100644
> > >> --- a/Documentation/devicetree/bindings/rtc/rtc-omap.txt
> > >> +++ b/Documentation/devicetree/bindings/rtc/rtc-omap.txt
> > >> @@ -6,6 +6,10 @@ Required properties:
> > >> - interrupts: rtc timer, alarm interrupts in order
> > >> - interrupt-parent: phandle for the interrupt controller
> > >>
> > >> +Optional properties:
> > >> +- ti,system-power-controller: Telling whether or not rtc is controlling
> > >> + the system power.
> > >> +
> > >> Example:
> > >>
> > >> rtc at 1c23000 {
> > >> @@ -14,4 +18,5 @@ rtc at 1c23000 {
> > >> interrupts = <19
> > >> 19>;
> > >> interrupt-parent = <&intc>;
> > >> + ti,system-power-controller;
> > >> };
> > >> diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
> > >> index 6009714..e6d4878 100644
> > >> --- a/drivers/rtc/rtc-omap.c
> > >> +++ b/drivers/rtc/rtc-omap.c
> > >> @@ -72,6 +72,14 @@
> > >> #define OMAP_RTC_KICK0_REG 0x6c
> > >> #define OMAP_RTC_KICK1_REG 0x70
> > >>
> > >> +#define OMAP_RTC_ALARM2_SECONDS_REG 0x80
> > >> +#define OMAP_RTC_ALARM2_MINUTES_REG 0x84
> > >> +#define OMAP_RTC_ALARM2_HOURS_REG 0x88
> > >> +#define OMAP_RTC_ALARM2_DAYS_REG 0x8c
> > >> +#define OMAP_RTC_ALARM2_MONTHS_REG 0x90
> > >> +#define OMAP_RTC_ALARM2_YEARS_REG 0x94
> > >> +#define OMAP_RTC_PMIC_REG 0x98
> > >> +
> > >> /* OMAP_RTC_CTRL_REG bit fields: */
> > >> #define OMAP_RTC_CTRL_SPLIT (1<<7)
> > >> #define OMAP_RTC_CTRL_DISABLE (1<<6)
> > >> @@ -93,15 +101,21 @@
> > >> #define OMAP_RTC_STATUS_BUSY (1<<0)
> > >>
> > >> /* OMAP_RTC_INTERRUPTS_REG bit fields: */
> > >> +#define OMAP_RTC_INTERRUPTS_IT_ALARM2 (1<<4)
> > >> #define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3)
> > >> #define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2)
> > >>
> > >> +/* OMAP_RTC_PMIC_REG bit fields: */
> > >> +#define OMAP_RTC_PMIC_POWER_EN_EN (1<<16)
> > >> +
> > >> /* OMAP_RTC_KICKER values */
> > >> #define KICK0_VALUE 0x83e70b13
> > >> #define KICK1_VALUE 0x95a4f1e0
> > >>
> > >> #define OMAP_RTC_HAS_KICKER 0x1
> > >>
> > >> +#define SHUTDOWN_TIME_SEC 2
> > >> +
> > >> static void __iomem *rtc_base;
> > >>
> > >> #define rtc_read(addr) readb(rtc_base + (addr))
> > >> @@ -290,6 +304,56 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
> > >> return 0;
> > >> }
> > >>
> > >> +/*
> > >> + * rtc_power_off: Set the pmic power off sequence. The RTC generates
> > >> + * pmic_pwr_enable control, which can be used to control an external
> > >> + * PMIC.
> > >> + */
> > >> +static void rtc_power_off(void)
> > >> +{
> > >> + u32 val;
> > >> + struct rtc_time tm;
> > >> + unsigned long time;
> > >> +
> > >> + /* Set PMIC power enable */
> > >> + val = readl(rtc_base + OMAP_RTC_PMIC_REG);
> > >> + writel(val | OMAP_RTC_PMIC_POWER_EN_EN, rtc_base + OMAP_RTC_PMIC_REG);
> > >> +
> > >> + /* Read rtc time */
> > >> + omap_rtc_read_time(NULL, &tm);
> > >> +
> > >> + /* Convert Gregorian date to seconds since 01-01-1970 00:00:00 */
> > >> + rtc_tm_to_time(&tm, &time);
> > >> +
> > >> + /* Add shutdown time to the current value */
> > >> + time += SHUTDOWN_TIME_SEC;
> > >> +
> > >> + /* Convert seconds since 01-01-1970 00:00:00 to Gregorian date */
> > >> + rtc_time_to_tm(time, &tm);
> > >> +
> > >> + if (tm2bcd(&tm) < 0)
> > >> + return;
> > >> +
> > >> + pr_info("System will go to power_off state in approx. %d secs\n",
> > >> + SHUTDOWN_TIME_SEC);
> > >> +
> > >> + /*
> > >> + * pmic_pwr_enable is controlled by means of ALARM2 event. So here
> > >> + * programming alarm2 expiry time and enabling alarm2 interrupt
> > >> + */
> > >> + rtc_write(tm.tm_sec, OMAP_RTC_ALARM2_SECONDS_REG);
> > >> + rtc_write(tm.tm_min, OMAP_RTC_ALARM2_MINUTES_REG);
> > >> + rtc_write(tm.tm_hour, OMAP_RTC_ALARM2_HOURS_REG);
> > >> + rtc_write(tm.tm_mday, OMAP_RTC_ALARM2_DAYS_REG);
> > >> + rtc_write(tm.tm_mon, OMAP_RTC_ALARM2_MONTHS_REG);
> > >> + rtc_write(tm.tm_year, OMAP_RTC_ALARM2_YEARS_REG);
> > >> +
> > >> + /* Enable alarm2 interrupt */
> > >> + val = readl(rtc_base + OMAP_RTC_INTERRUPTS_REG);
> > >> + writel(val | OMAP_RTC_INTERRUPTS_IT_ALARM2,
> > >> + rtc_base + OMAP_RTC_INTERRUPTS_REG);
> > >> +}
> > >> +
> > >> static struct rtc_class_ops omap_rtc_ops = {
> > >> .read_time = omap_rtc_read_time,
> > >> .set_time = omap_rtc_set_time,
> > >> @@ -327,12 +391,16 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
> > >> struct resource *res, *mem;
> > >> struct rtc_device *rtc;
> > >> u8 reg, new_ctrl;
> > >> + bool pm_off = false;
> > >> const struct platform_device_id *id_entry;
> > >> const struct of_device_id *of_id;
> > >>
> > >> of_id = of_match_device(omap_rtc_of_match, &pdev->dev);
> > >> - if (of_id)
> > >> + if (of_id) {
> > >> pdev->id_entry = of_id->data;
> > >> + pm_off = of_property_read_bool(pdev->dev.of_node,
> > >> + "ti,system-power-controller");
> > >> + }
> > >>
> > >> omap_rtc_timer = platform_get_irq(pdev, 0);
> > >> if (omap_rtc_timer <= 0) {
> > >> @@ -385,6 +453,10 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
> > >> platform_set_drvdata(pdev, rtc);
> > >> dev_set_drvdata(&rtc->dev, mem);
> > >>
> > >> + /* RTC power off */
> > >> + if (pm_off && !pm_power_off)
> > >> + pm_power_off = rtc_power_off;
> > >> +
> > >> /* clear pending irqs, and set 1/second periodic,
> > >> * which we'll use instead of update irqs
> > >> */
> > >> --
> > >> 1.7.9.5
> > >>
> > >> --
> > >> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> > >> the body of a message to majordomo at vger.kernel.org
> > >> More majordomo info at http://vger.kernel.org/majordomo-info.html
> >
>
>
^ permalink raw reply
* [PATCH v7 0/3] Yet another update for the Cortex-M3 series
From: Uwe Kleine-König @ 2013-01-11 9:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1350462872-16805-1-git-send-email-u.kleine-koenig@pengutronix.de>
Hello Russell,
On Wed, Oct 17, 2012 at 10:34:29AM +0200, Uwe Kleine-K?nig wrote:
> the only change since v6 is a rebase on top of v3.7-rc1 and so on Al
> Viro's changes to kernel_execve().
>
> These patches merge just fine into today's next and I put them into my
> branch that Stephen will pick for the next next.
>
> As before this doesn't make a functional M3 port as there are still some
> missing items. If you want to see the code live I also updated the efm32
> branch in my repository to be based on these patches. This code works,
> but isn't suitable for mainline yet. You can run it on EnergyMicro's
> efm32 devboard.
>
> Best regards
> Uwe
>
> Catalin Marinas (1):
> Cortex-M3: Add base support for Cortex-M3
>
> Uwe Kleine-K?nig (2):
> ARM: make cr_alignment read-only #ifndef CONFIG_CPU_CP15
> Cortex-M3: Add support for exception handling
These patches are in next since next-20121018 without any reported
problems. What do you think about inclusion for 3.9-rc1?
They are based on 3.7-rc1 and I'm currently porting my tree to 3.8-rc3
to test there.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [RFC 0/4] TI LCDC DRM driver
From: Laurent Pinchart @ 2013-01-11 9:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAF6AEGu4KJ27R6P7CiewVYSP22ZX+2=s6ZeNJv+Voh06gntBzg@mail.gmail.com>
Hi Rob,
On Thursday 10 January 2013 21:15:26 Rob Clark wrote:
> On Thu, Jan 10, 2013 at 6:05 PM, Laurent Pinchart wrote:
> > On Thursday 10 January 2013 10:16:10 Dave Airlie wrote:
> >> On Wed, Jan 9, 2013 at 2:11 PM, Rob Clark <robdclark@gmail.com> wrote:
> >> > Updated version of DRM driver for TI LCD Controller. Since the initial
> >> > version of the patch, which only supported TFP410 DVI output, I've
> >> > added
> >> > an output driver for LCD panels (for example, LCD3 or LCD7 cape for the
> >> > beagle-bone), and initial support for HDMI output via NXP TDA19988 HDMI
> >> > encoder (via i2c encoder-slave output driver).
> >> >
> >> > At this point, I think the basic lcdc drm driver plus TFP410 DVI output
> >> > (first patch) is in reasonable shape (barring potential rename, if lcdc
> >> > is too generic of a name... but I was not feeling creative enough yet
> >> > to
> >> > pick a new name).
> >>
> >> I'd like at least tilcdc :-)
> >
> > So do I :-) The Renesas LCD controller is also called LCDC, and they
> > called the fbdev driver sh_mobile_lcdcfb. tilcdc isn't *that* long in
> > comparison :-)
>
> next version will be 'tilcdc' :-)
>
> I would appreciate some thoughts about more generic devicetree lcd
> panel parameters for the (ti)lcdc_panel patch.. from a functional
> standpoint, I think the lcd panel support part is also pretty much
> ready to go (I've added backlight support since the last version I
> sent), but I'm not really happy with the DT bindings for that because
> they seem to me a bit too hw specific, but I'm not really sure how
> they should look.
How urgent is that ? I will be offline next week, can it wait until I come
back ? (That's more of a rhetorical question I'm afraid, as I'm pretty sure I
won't have time to review that today :-S)
> Fwiw, on the CDF <-> KMS end of things, I'm sort of thinking the i2c
> encoder slave is not too far off.. just needs to be a bit decoupled
> from i2c.
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH 04/14] usb: phy: nop: Handle power supply regulator for the PHY
From: Roger Quadros @ 2013-01-11 9:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <50EF0324.9060004@mvista.com>
On 01/10/2013 08:06 PM, Sergei Shtylyov wrote:
> Hello.
>
> On 01/10/2013 07:51 PM, Roger Quadros wrote:
>
>> We use "vcc" as the supply name for the PHY's power supply.
>> The power supply will be enabled during .init() and disabled
>> during .shutdown()
>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>> drivers/usb/otg/nop-usb-xceiv.c | 18 ++++++++++++++++++
>> 1 files changed, 18 insertions(+), 0 deletions(-)
>
>> diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c
>> index 163f972..1c6db10 100644
>> --- a/drivers/usb/otg/nop-usb-xceiv.c
>> +++ b/drivers/usb/otg/nop-usb-xceiv.c
> [...]
>> @@ -70,6 +72,11 @@ static int nop_init(struct usb_phy *phy)
>> {
>> struct nop_usb_xceiv *nop = dev_get_drvdata(phy->dev);
>>
>> + if (nop->vcc) {
>> + if (regulator_enable(nop->vcc))
>> + dev_err(phy->dev, "Failed to enable power\n");
>> + }
>
> Could be collapsed into single *if*.
Right.
>
>> +
>> if (nop->clk)
>> clk_enable(nop->clk);
>>
>> @@ -82,6 +89,11 @@ static void nop_shutdown(struct usb_phy *phy)
>>
>> if (nop->clk)
>> clk_disable(nop->clk);
>> +
>> + if (nop->vcc) {
>> + if (regulator_disable(nop->vcc))
>> + dev_err(phy->dev, "Failed to disable power\n");
>> + }
>
> Same here.
OK. I'll fix them in next spin.
--cheers,
-roger
^ permalink raw reply
* [PATCH 01/14] mfd: omap-usb-host: Consolidate OMAP USB-HS platform data
From: Roger Quadros @ 2013-01-11 9:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20130110234537.GB15458@atomide.com>
Tony,
On 01/11/2013 01:45 AM, Tony Lindgren wrote:
> * Roger Quadros <rogerq@ti.com> [130110 08:54]:
>> Let's have a single platform data structure for the OMAP's High-Speed
>> USB host subsystem instead of having 3 separate ones i.e. one for
>> board data, one for USB Host (UHH) module and one for USB-TLL module.
>>
>> This makes the code much simpler and avoids creating multiple copies of
>> platform data.
>
> I can apply just this patch alone into an immutable branch that
> we all can merge in as needed as long as we have acks for the USB
> and MFD parts.
>
> Or does this one need to be changed based on Alan's comments
> on the EHCI lib related changes?
>
This does not depend on EHCI lib based changes but it depends on the
OMAP USB Host cleanup series posted earlier.
regards,
-roger
^ permalink raw reply
* [PATCH 1/2] ARM: shmobile: sh73a0: Add CPU sleep suspend
From: Guennadi Liakhovetski @ 2013-01-11 9:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20121214134727.GL16382@verge.net.au>
Hi Simon
On Fri, 14 Dec 2012, Simon Horman wrote:
> On Fri, Dec 14, 2012 at 12:23:06PM +0900, Magnus Damm wrote:
> > On Wed, Dec 5, 2012 at 9:13 PM, Bastian Hecht <hechtb@gmail.com> wrote:
> > > From: Bastian Hecht <hechtb@gmail.com>
> > >
> > > Add the lighest possible sleep mode on Cortex-A9 cores: CPU sleep. It is
> > > entered by a simple dsb and wfi instruction via cpu_do_idle(). As just
> > > clocks are stopped there is no need to save or restore any state of the
> > > system.
> > >
> > > Signed-off-by: Bastian Hecht <hechtb+renesas@gmail.com>
> >
> > Acked-by: Magnus Damm <damm@opensource.se>
>
> Hi Bastian,
>
> could you please re-spin this series on top of the soc5 or next
> branches of my renesas tree on kernel.org?
>
> Feel free to include Magnus's Ack unless you make any
> non-trivial changes.
It looks like this commit in your tree
http://git.kernel.org/?p=linux/kernel/git/horms/renesas.git;a=commitdiff;h=1662b83628a0c6fd6d8a2a0dcf9b67577906e75b
is broken, am I right?
Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
^ permalink raw reply
* [PATCH v4 1/4] rtc: OMAP: Add system pm_power_off to rtc driver
From: AnilKumar, Chimata @ 2013-01-11 9:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CA+Bv8XaZzWindjhYnXLaqq5mJ6X0Hq=C7NUxW3aK3eh-d6ghtg@mail.gmail.com>
On Fri, Jan 11, 2013 at 14:24:46, Russ Dill wrote:
> On Fri, Jan 11, 2013 at 12:08 AM, Russ Dill <russ.dill@gmail.com> wrote:
> > On Thu, Dec 13, 2012 at 10:03 PM, AnilKumar Ch <anilkumar@ti.com> wrote:
> >> From: Colin Foe-Parker <colin.foeparker@logicpd.com>
> >>
> >> Add system power off control to rtc driver which is the in-charge
> >> of controlling the BeagleBone system power. The power_off routine
> >> can be hooked up to "pm_power_off" system call.
> >>
> >> System power off sequence:-
> >> * Set PMIC STATUS_OFF when PMIC_POWER_EN is pulled low
> >> * Enable PMIC_POWER_EN in rtc module
> >> * Set rtc ALARM2 time
> >> * Enable ALARM2 interrupt
> >>
> >> Signed-off-by: Colin Foe-Parker <colin.foeparker@logicpd.com>
> >> [anilkumar at ti.com: move poweroff additions to rtc driver]
> >> Signed-off-by: AnilKumar Ch <anilkumar@ti.com>
> >
> > Looks good
> >
> > Reviewed-by: Russ Dill <russ.dill@ti.com>
> > Acked-by: Russ Dill <russ.dill@ti.com>
>
> Sorry, actually, small follow up. Is there any reason this uses
> readl/writel in some places rather than rtc_read/rtc_write?
Hi Russ Dill,
Thanks for the review
At OMAP_RTC_PMIC_POWER_EN_EN, 32-bit value needs to modified so
readl/writel are used. While enabling the INTERRUPTS we can change
it to rtc_read/rtc_write but I am not seeing any advantage if we
do that apart from consistency.
Thanks
AnilKumar
>
> >> ---
> >> Documentation/devicetree/bindings/rtc/rtc-omap.txt | 5 ++
> >> drivers/rtc/rtc-omap.c | 74 +++++++++++++++++++-
> >> 2 files changed, 78 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/Documentation/devicetree/bindings/rtc/rtc-omap.txt b/Documentation/devicetree/bindings/rtc/rtc-omap.txt
> >> index b47aa41..8d9f4f9 100644
> >> --- a/Documentation/devicetree/bindings/rtc/rtc-omap.txt
> >> +++ b/Documentation/devicetree/bindings/rtc/rtc-omap.txt
> >> @@ -6,6 +6,10 @@ Required properties:
> >> - interrupts: rtc timer, alarm interrupts in order
> >> - interrupt-parent: phandle for the interrupt controller
> >>
> >> +Optional properties:
> >> +- ti,system-power-controller: Telling whether or not rtc is controlling
> >> + the system power.
> >> +
> >> Example:
> >>
> >> rtc at 1c23000 {
> >> @@ -14,4 +18,5 @@ rtc at 1c23000 {
> >> interrupts = <19
> >> 19>;
> >> interrupt-parent = <&intc>;
> >> + ti,system-power-controller;
> >> };
> >> diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
> >> index 6009714..e6d4878 100644
> >> --- a/drivers/rtc/rtc-omap.c
> >> +++ b/drivers/rtc/rtc-omap.c
> >> @@ -72,6 +72,14 @@
> >> #define OMAP_RTC_KICK0_REG 0x6c
> >> #define OMAP_RTC_KICK1_REG 0x70
> >>
> >> +#define OMAP_RTC_ALARM2_SECONDS_REG 0x80
> >> +#define OMAP_RTC_ALARM2_MINUTES_REG 0x84
> >> +#define OMAP_RTC_ALARM2_HOURS_REG 0x88
> >> +#define OMAP_RTC_ALARM2_DAYS_REG 0x8c
> >> +#define OMAP_RTC_ALARM2_MONTHS_REG 0x90
> >> +#define OMAP_RTC_ALARM2_YEARS_REG 0x94
> >> +#define OMAP_RTC_PMIC_REG 0x98
> >> +
> >> /* OMAP_RTC_CTRL_REG bit fields: */
> >> #define OMAP_RTC_CTRL_SPLIT (1<<7)
> >> #define OMAP_RTC_CTRL_DISABLE (1<<6)
> >> @@ -93,15 +101,21 @@
> >> #define OMAP_RTC_STATUS_BUSY (1<<0)
> >>
> >> /* OMAP_RTC_INTERRUPTS_REG bit fields: */
> >> +#define OMAP_RTC_INTERRUPTS_IT_ALARM2 (1<<4)
> >> #define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3)
> >> #define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2)
> >>
> >> +/* OMAP_RTC_PMIC_REG bit fields: */
> >> +#define OMAP_RTC_PMIC_POWER_EN_EN (1<<16)
> >> +
> >> /* OMAP_RTC_KICKER values */
> >> #define KICK0_VALUE 0x83e70b13
> >> #define KICK1_VALUE 0x95a4f1e0
> >>
> >> #define OMAP_RTC_HAS_KICKER 0x1
> >>
> >> +#define SHUTDOWN_TIME_SEC 2
> >> +
> >> static void __iomem *rtc_base;
> >>
> >> #define rtc_read(addr) readb(rtc_base + (addr))
> >> @@ -290,6 +304,56 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
> >> return 0;
> >> }
> >>
> >> +/*
> >> + * rtc_power_off: Set the pmic power off sequence. The RTC generates
> >> + * pmic_pwr_enable control, which can be used to control an external
> >> + * PMIC.
> >> + */
> >> +static void rtc_power_off(void)
> >> +{
> >> + u32 val;
> >> + struct rtc_time tm;
> >> + unsigned long time;
> >> +
> >> + /* Set PMIC power enable */
> >> + val = readl(rtc_base + OMAP_RTC_PMIC_REG);
> >> + writel(val | OMAP_RTC_PMIC_POWER_EN_EN, rtc_base + OMAP_RTC_PMIC_REG);
> >> +
> >> + /* Read rtc time */
> >> + omap_rtc_read_time(NULL, &tm);
> >> +
> >> + /* Convert Gregorian date to seconds since 01-01-1970 00:00:00 */
> >> + rtc_tm_to_time(&tm, &time);
> >> +
> >> + /* Add shutdown time to the current value */
> >> + time += SHUTDOWN_TIME_SEC;
> >> +
> >> + /* Convert seconds since 01-01-1970 00:00:00 to Gregorian date */
> >> + rtc_time_to_tm(time, &tm);
> >> +
> >> + if (tm2bcd(&tm) < 0)
> >> + return;
> >> +
> >> + pr_info("System will go to power_off state in approx. %d secs\n",
> >> + SHUTDOWN_TIME_SEC);
> >> +
> >> + /*
> >> + * pmic_pwr_enable is controlled by means of ALARM2 event. So here
> >> + * programming alarm2 expiry time and enabling alarm2 interrupt
> >> + */
> >> + rtc_write(tm.tm_sec, OMAP_RTC_ALARM2_SECONDS_REG);
> >> + rtc_write(tm.tm_min, OMAP_RTC_ALARM2_MINUTES_REG);
> >> + rtc_write(tm.tm_hour, OMAP_RTC_ALARM2_HOURS_REG);
> >> + rtc_write(tm.tm_mday, OMAP_RTC_ALARM2_DAYS_REG);
> >> + rtc_write(tm.tm_mon, OMAP_RTC_ALARM2_MONTHS_REG);
> >> + rtc_write(tm.tm_year, OMAP_RTC_ALARM2_YEARS_REG);
> >> +
> >> + /* Enable alarm2 interrupt */
> >> + val = readl(rtc_base + OMAP_RTC_INTERRUPTS_REG);
> >> + writel(val | OMAP_RTC_INTERRUPTS_IT_ALARM2,
> >> + rtc_base + OMAP_RTC_INTERRUPTS_REG);
> >> +}
> >> +
> >> static struct rtc_class_ops omap_rtc_ops = {
> >> .read_time = omap_rtc_read_time,
> >> .set_time = omap_rtc_set_time,
> >> @@ -327,12 +391,16 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
> >> struct resource *res, *mem;
> >> struct rtc_device *rtc;
> >> u8 reg, new_ctrl;
> >> + bool pm_off = false;
> >> const struct platform_device_id *id_entry;
> >> const struct of_device_id *of_id;
> >>
> >> of_id = of_match_device(omap_rtc_of_match, &pdev->dev);
> >> - if (of_id)
> >> + if (of_id) {
> >> pdev->id_entry = of_id->data;
> >> + pm_off = of_property_read_bool(pdev->dev.of_node,
> >> + "ti,system-power-controller");
> >> + }
> >>
> >> omap_rtc_timer = platform_get_irq(pdev, 0);
> >> if (omap_rtc_timer <= 0) {
> >> @@ -385,6 +453,10 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
> >> platform_set_drvdata(pdev, rtc);
> >> dev_set_drvdata(&rtc->dev, mem);
> >>
> >> + /* RTC power off */
> >> + if (pm_off && !pm_power_off)
> >> + pm_power_off = rtc_power_off;
> >> +
> >> /* clear pending irqs, and set 1/second periodic,
> >> * which we'll use instead of update irqs
> >> */
> >> --
> >> 1.7.9.5
> >>
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> >> the body of a message to majordomo at vger.kernel.org
> >> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
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