* [PATCH v2 2/3] arm/tegra: add support for ventana pinmuxing
From: Peter De Schrijver @ 2011-09-27 18:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOesGMjqhGYUQ2XmuBBTBSUA6mKnOLF=Hmi86hRQhLiUMPtiBg@mail.gmail.com>
On Tue, Sep 27, 2011 at 07:36:24PM +0200, Olof Johansson wrote:
> Hi,
>
> The series looks reasonable to me, I'll apply it together with some of
> the other pending tegra patches from the list. Once Stephen's pinmux
> devicetree code is in place some of this can be removed.
>
> One comment on this patch description though:
>
>
> On Tue, Sep 27, 2011 at 10:10 AM, Peter De Schrijver
> <pdeschrijver@nvidia.com> wrote:
> > Add support for ventana pinmuxing as a seaboard derivative. This is a cut down
> > version of chromeos kernel commit 772f1b56e713be7a55759c2d5eadb9eb11d078db
> > by Jong Kim <jongk@nvidia.com>.
>
> Having a reference to a SHA1 in a foreign source tree isn't really
> useful in the mainline kernel commit log.
>
> I would just phrase it "This is a cut down version of work done by <....>"
>
Ok. I will resend this series with the updated description.
Cheers,
Peter.
^ permalink raw reply
* [RFC 2/5] ARM: OMAP: omap_device: add a method to set iommu private archdata
From: Ohad Ben-Cohen @ 2011-09-27 18:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87sjni9aql.fsf@ti.com>
Hi Kevin,
On Tue, Sep 27, 2011 at 1:53 AM, Kevin Hilman <khilman@ti.com> wrote:
> Benoit did just this in preparation for DT.
>
> ? ? ? http://marc.info/?l=linux-omap&m=131672480111927&w=2
>
> Will that meet your needs?
It's almost there, but not entirely.
Benoit's alloc/delete functions focus on the omap_device part, leaving
the handling of the platform device (allocation and pdata setting) to
omap_device_build_ss(), which at the same time registers the pdev.
I'd need to split omap_device_build_ss() into two: an alloc() part
which does everything but registering the pdev, and a register() part.
Users will first call alloc(), manually set archdata members, and then
call the register() part.
Something like this (compile-tested only, based on Benoit's
for_3.2/4_omap4_dt_early_devices branch):
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 0ae9e7f..9b8008c 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -671,7 +671,7 @@ struct platform_device *omap_device_build(const
char *pdev_name, int pdev_id,
}
/**
- * omap_device_build_ss - build and register an omap_device with
multiple hwmods
+ * omap_device_alloc_ss - build an omap_device with multiple hwmods
* @pdev_name: name of the platform_device driver to use
* @pdev_id: this platform_device's connection ID
* @oh: ptr to the single omap_hwmod that backs this omap_device
@@ -679,19 +679,19 @@ struct platform_device *omap_device_build(const
char *pdev_name, int pdev_id,
* @pdata_len: amount of memory pointed to by @pdata
* @pm_lats: pointer to a omap_device_pm_latency array for this device
* @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
- * @is_early_device: should the device be registered as an early device or not
*
- * Convenience function for building and registering an omap_device
+ * Convenience function for building (only) an omap_device
* subsystem record. Subsystem records consist of multiple
- * omap_hwmods. This function in turn builds and registers a
- * platform_device record. Returns an ERR_PTR() on error, or passes
- * along the return value of omap_device_register().
+ * omap_hwmods. This function in turn builds (but doesn't register) a
+ * platform_device record, so callers can manipulate it (typically by
+ * setting one or more archdata members) before it's registered.
+ * Returns an ERR_PTR() on error, or the allocated pdev on success.
*/
-struct platform_device *omap_device_build_ss(const char *pdev_name,
int pdev_id,
+struct platform_device *omap_device_alloc_ss(const char *pdev_name,
int pdev_id,
struct omap_hwmod **ohs, int oh_cnt,
void *pdata, int pdata_len,
struct omap_device_pm_latency *pm_lats,
- int pm_lats_cnt, int is_early_device)
+ int pm_lats_cnt)
{
int ret = -ENOMEM;
struct platform_device *pdev;
@@ -723,13 +723,6 @@ struct platform_device
*omap_device_build_ss(const char *pdev_name, int pdev_id,
if (ret)
goto odbs_exit2;
- if (is_early_device)
- ret = omap_early_device_register(pdev);
- else
- ret = omap_device_register(pdev);
- if (ret)
- goto odbs_exit2;
-
return pdev;
odbs_exit2:
@@ -744,6 +737,93 @@ odbs_exit:
}
/**
+ * omap_device_delete_ss - free an omap_device-based platform device
+ * @pdev: platform_device that represents this omap_device
+ *
+ * Convenience function for freeing a platform_device record, which
+ * is based on an omap_device subsystem record.
+ *
+ * Use this function only if @pdev was created using omap_device_alloc_ss(),
+ * most commonly because a subsequent call to omap_device_register_ss() failed.
+ */
+void omap_device_delete_ss(struct platform_device *pdev)
+{
+ struct omap_device *od = to_omap_device(pdev);
+
+ omap_device_delete(od);
+ platform_device_put(pdev);
+}
+
+/**
+ * omap_device_register_ss - register an omap_device-based platform device
+ * @pdev: platform_device that represents this omap_device
+ * @is_early_device: should the device be registered as an early device or not
+ *
+ * Convenience function for registering a platform_device record, which
+ * is based on an omap_device subsystem record, which was created using
+ * omap_device_alloc_ss().
+ *
+ * Returns 0 on success, or an appropriate error value otherwise (essentially
+ * by returning the value of platform_device_register())
+ */
+int omap_device_register_ss(struct platform_device *pdev, int is_early_device)
+{
+ int ret;
+
+ if (is_early_device)
+ ret = omap_early_device_register(pdev);
+ else
+ ret = omap_device_register(pdev);
+
+ return ret;
+}
+
+/**
+ * omap_device_build_ss - build and register an omap_device with
multiple hwmods
+ * @pdev_name: name of the platform_device driver to use
+ * @pdev_id: this platform_device's connection ID
+ * @oh: ptr to the single omap_hwmod that backs this omap_device
+ * @pdata: platform_data ptr to associate with the platform_device
+ * @pdata_len: amount of memory pointed to by @pdata
+ * @pm_lats: pointer to a omap_device_pm_latency array for this device
+ * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
+ * @is_early_device: should the device be registered as an early device or not
+ *
+ * Convenience function for building and registering an omap_device
+ * subsystem record. Subsystem records consist of multiple
+ * omap_hwmods. This function in turn builds and registers a
+ * platform_device record. Returns an ERR_PTR() on error, or passes
+ * along the built pdev on success.
+ */
+struct platform_device *omap_device_build_ss(const char *pdev_name,
int pdev_id,
+ struct omap_hwmod **ohs, int oh_cnt,
+ void *pdata, int pdata_len,
+ struct omap_device_pm_latency *pm_lats,
+ int pm_lats_cnt, int is_early_device)
+{
+ struct platform_device *pdev;
+ int ret;
+
+ pdev = omap_device_alloc_ss(pdev_name, pdev_id, ohs, oh_cnt, pdata,
+ pdata_len, pm_lats, pm_lats_cnt);
+
+ if (IS_ERR(pdev))
+ goto out;
+
+ ret = omap_device_register_ss(pdev, is_early_device);
+ if (ret) {
+ pdev = ERR_PTR(ret);
+ goto delete_od;
+ }
+
+ return pdev;
+delete_od:
+ omap_device_delete_ss(pdev);
+out:
+ return pdev;
+}
+
+/**
* omap_early_device_register - register an omap_device as an early platform
* device.
* @od: struct omap_device * to register
That's the idea; please tell me how you'd like to see this go forward
(there are at least several personal-taste issues here, e.g., naming:
now we have two sets of alloc/delete functions which have different
semantics) and which branch would you like me to base this work off of
(not sure if Benoit's patches already went into your
for_3.2/omap_device branch) and I'll respin this patch properly.
Thanks a lot!
Ohad.
^ permalink raw reply related
* [PATCH v3 1/6] iommu/core: split mapping to page sizes as supported by the hardware
From: Roedel, Joerg @ 2011-09-27 18:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAK=WgbYG2tpMJ2SikZhm=R9j5kQ6Hm8CGg=q1bko3idzF53Q3Q@mail.gmail.com>
On Tue, Sep 27, 2011 at 09:28:37AM -0400, Ohad Ben-Cohen wrote:
> So you're suggesting to re-implement find_next_bit() using ffs()/fls()
> and shifting ?
No. I suggest a simpler and shorter algorithm using the bit helpers.
Something like that:
min_idx = __ffs(iommu_page_sizes);
while (size) {
/* Max alignment allowed by current physical address */
phys_idx = __ffs(phys);
/* Max alignment allowed by current size */
size_idx = __fls(size);
/* special case: iova == 0 */
if (likely(phys))
idx = min(phys_idx, size_idx);
else
idx = size_idx;
BUG_ON(idx < min_idx);
psize = 1UL << idx;
/* search next smaller page-size supported */
while (psize && !(iommu_page_sizes & psize))
psize >>= 1;
BUG_ON(psize == 0);
iommu_ops->map(domain, iova, phys, get_order(psize), prot);
iova += psize;
phys += psize;
size -= psize;
}
It is only C-style pseudo-code, of course. These __ffs and __fls lines
all translate to a single instruction later. The find_next_bit()
function has a lot more overhead because it needs to take account of
real bitmaps (arrays of ulong). But this complexity is not required
here.
And yes, overhead is important when we implement the generic dma-ops
on-top of the iommu-api because this will make the iommu_map function a
fast-path. So we really care about overhead here.
Joerg
--
AMD Operating System Research Center
Advanced Micro Devices GmbH Einsteinring 24 85609 Dornach
General Managers: Alberto Bozzo, Andrew Bowd
Registration: Dornach, Landkr. Muenchen; Registerger. Muenchen, HRB Nr. 43632
^ permalink raw reply
* [RFC PATCH 0/3] Add accurate boot timing to a Linux system
From: Simon Glass @ 2011-09-27 18:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAErSpo63fYmQVRO2O3sB37k6rAo7Qttdh1xo=WH+QwcVb+neGg@mail.gmail.com>
Hi Bjorn,
On Sun, Sep 25, 2011 at 5:54 AM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Fri, Sep 23, 2011 at 5:03 PM, Simon Glass <sjg@chromium.org> wrote:
>> This experimental patch set adds boot timing to a Linux system. The
>> timing starts with the boot loader and extends through the kernel into
>> user space to the completion of the boot process. The timing starts when
>> the system leaves reset, not later when the kernel starts.
>>
>> The concept is:
>> - Boot loader records a timestamp for key events during its operation
>> - These timestamps are passed to Linux, which adds more as it boots
>> - These timestamps are made available to user space, where more
>> timestamps are added as init does its job
>> - Finally the whole record is collected by a user-space script run at
>> the end of init. This is fed back through some mechanism to monitor
>> boot time in the field.
>
> I think this is a cool idea. ?It's quite difficult to extract this
> sort of information today, and making it easily and consistently
> available should help focus attention and improve things.
>
> There are difficult issues about which clock to use, how to correlate
> bootloader & kernel timestamps, how to make sure the timestamps stay
> sensible even when we use hwclock, ntp, etc., but I think it's worth
> pushing on this to see how far you can go.
Yes it is not easy to get all of this right, especially trying to
cross two completely different projects. I think the timestamps should
be measured from reset. The kernel timestamps start not at zero, but
from the time the kernel starts. This guarantees a consistent time
base across the data. Also if there is a pre-boot program (such as a
NAND loader) then its time will be counted also.
A good timer would be an accurate monotonic wall clock, not
necessarily related to time of day. An ideal timer would be a
microsecond/nanosecond timer maintained by the hardware / SOC.
Regards,
Simon
>
> Bjorn
>
^ permalink raw reply
* [PATCH V2] Add platform driver support to the CS890x driver
From: Jaccon Bastiaansen @ 2011-09-27 18:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110913074626.GM28624@pengutronix.de>
The CS89x0 ethernet controller is used on a number of evaluation
boards, such as the MX31ADS. The current driver has memory address and
IRQ settings for each board on which this controller is used. Driver
updates are therefore required to support other boards that also use
the CS89x0. To avoid these driver updates, a better mechanism
(platform driver support) is added to communicate the board dependent
settings to the driver.
Signed-off-by: Jaccon Bastiaansen <jaccon.bastiaansen@gmail.com>
---
arch/arm/mach-imx/mach-mx31ads.c | 40 ++++++-
arch/arm/mach-ixp2000/ixdp2x01.c | 24 +++-
arch/arm/mach-ixp2000/pci.c | 3 +-
arch/arm/mach-ixp23xx/ixdp2351.c | 21 +++
arch/arm/mach-ixp23xx/pci.c | 3 +-
arch/arm/plat-mxc/include/mach/board-mx31ads.h | 33 -----
drivers/net/Kconfig | 16 ++-
drivers/net/Space.c | 2 +-
drivers/net/cs89x0.c | 175 +++++++++++++++---------
9 files changed, 210 insertions(+), 107 deletions(-)
delete mode 100644 arch/arm/plat-mxc/include/mach/board-mx31ads.h
diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c
index f4dee02..007bd38 100644
--- a/arch/arm/mach-imx/mach-mx31ads.c
+++ b/arch/arm/mach-imx/mach-mx31ads.c
@@ -28,7 +28,6 @@
#include <asm/memory.h>
#include <asm/mach/map.h>
#include <mach/common.h>
-#include <mach/board-mx31ads.h>
#include <mach/iomux-mx3.h>
#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
@@ -62,6 +61,7 @@
#define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS)
#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4)
+#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE)
#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10)
@@ -69,6 +69,18 @@
#define MXC_MAX_EXP_IO_LINES 16
+
+/* Base address of PBC controller */
+#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT
+
+/* Offsets for the PBC Controller register */
+
+/* Ethernet Controller IO addresses */
+#define PBC_CS8900A_IOBASE 0x020000
+#define CS8900A_START (PBC_BASE_ADDRESS + PBC_CS8900A_IOBASE + 0x300)
+
+#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8)
+
/*
* The serial port definition structure.
*/
@@ -101,11 +113,36 @@ static struct platform_device serial_device = {
},
};
+static struct resource mx31ads_cs8900_resources[] = {
+ {
+ .start = (u32)CS8900A_START,
+ .end = (u32)CS8900A_START + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = EXPIO_INT_ENET_INT,
+ .end = EXPIO_INT_ENET_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mx31ads_cs8900_device = {
+ .name = "cs89x0",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mx31ads_cs8900_resources),
+ .resource = mx31ads_cs8900_resources,
+};
+
static int __init mxc_init_extuart(void)
{
return platform_device_register(&serial_device);
}
+static void __init mxc_init_ext_ethernet(void)
+{
+ platform_device_register(&mx31ads_cs8900_device);
+}
+
static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -520,6 +557,7 @@ static void __init mx31ads_init(void)
mxc_init_imx_uart();
mxc_init_i2c();
mxc_init_audio();
+ mxc_init_ext_ethernet();
}
static void __init mx31ads_timer_init(void)
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index 84835b2..1ec4a74 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -394,9 +394,31 @@ static struct platform_device ixdp2x01_i2c_controller = {
.num_resources = 0
};
+static struct resource ixdp2x01_cs8900_resources[] = {
+ {
+ .start = (u32)IXDP2X01_CS8900_VIRT_BASE,
+ .end = (u32)IXDP2X01_CS8900_VIRT_BASE + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_IXDP2X01_CS8900,
+ .end = IRQ_IXDP2X01_CS8900,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ixdp2x01_cs8900 = {
+ .name = "cs89x0",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(ixdp2x01_cs8900_resources),
+ .resource = ixdp2x01_cs8900_resources,
+};
+
+
static struct platform_device *ixdp2x01_devices[] __initdata = {
&ixdp2x01_flash,
- &ixdp2x01_i2c_controller
+ &ixdp2x01_i2c_controller,
+ &ixdp2x01_cs8900
};
static void __init ixdp2x01_init_machine(void)
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
index f797c5f..54bf1b8 100644
--- a/arch/arm/mach-ixp2000/pci.c
+++ b/arch/arm/mach-ixp2000/pci.c
@@ -130,7 +130,8 @@ static struct pci_ops ixp2000_pci_ops = {
.write = ixp2000_pci_write_config
};
-struct pci_bus *ixp2000_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
+struct pci_bus __devinit
+*ixp2000_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
{
return pci_scan_bus(sysdata->busnr, &ixp2000_pci_ops, sysdata);
}
diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c
index 8dcba17..d559110 100644
--- a/arch/arm/mach-ixp23xx/ixdp2351.c
+++ b/arch/arm/mach-ixp23xx/ixdp2351.c
@@ -311,6 +311,26 @@ static struct platform_device ixdp2351_flash = {
.resource = &ixdp2351_flash_resource,
};
+static struct resource ixdp2351_cs8900_resources[] = {
+ {
+ .start = (u32)IXDP2351_VIRT_CS8900_BASE,
+ .end = (u32)IXDP2351_VIRT_CS8900_BASE + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_IXDP2351_CS8900,
+ .end = IRQ_IXDP2351_CS8900,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ixdp2351_cs8900 = {
+ .name = "cs89x0",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(ixdp2351_cs8900_resources),
+ .resource = ixdp2351_cs8900_resources,
+};
+
static void __init ixdp2351_init(void)
{
platform_device_register(&ixdp2351_flash);
@@ -323,6 +343,7 @@ static void __init ixdp2351_init(void)
IXP23XX_EXP_CS0[2] |= IXP23XX_FLASH_WRITABLE;
IXP23XX_EXP_CS0[3] |= IXP23XX_FLASH_WRITABLE;
+ platform_device_register(&ixdp2351_cs8900);
ixp23xx_sys_init();
}
diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c
index 563819a..f82bb91 100644
--- a/arch/arm/mach-ixp23xx/pci.c
+++ b/arch/arm/mach-ixp23xx/pci.c
@@ -141,7 +141,8 @@ struct pci_ops ixp23xx_pci_ops = {
.write = ixp23xx_pci_write_config,
};
-struct pci_bus *ixp23xx_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
+struct pci_bus __devinit
+*ixp23xx_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
{
return pci_scan_bus(sysdata->busnr, &ixp23xx_pci_ops, sysdata);
}
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
deleted file mode 100644
index 94b60dd..0000000
--- a/arch/arm/plat-mxc/include/mach/board-mx31ads.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * 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 __ASM_ARCH_MXC_BOARD_MX31ADS_H__
-#define __ASM_ARCH_MXC_BOARD_MX31ADS_H__
-
-#include <mach/hardware.h>
-
-/*
- * These symbols are used by drivers/net/cs89x0.c.
- * This is ugly as hell, but we have to provide them until
- * someone fixed the driver.
- */
-
-/* Base address of PBC controller */
-#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT
-/* Offsets for the PBC Controller register */
-
-/* Ethernet Controller IO base address */
-#define PBC_CS8900A_IOBASE 0x020000
-
-#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
-
-#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8)
-
-#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 93359fa..2873f86 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1497,8 +1497,7 @@ config FORCEDETH
config CS89x0
tristate "CS89x0 support"
- depends on NET_ETHERNET && (ISA || EISA || MACH_IXDP2351 \
- || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440)
+ depends on NET_ETHERNET
---help---
Support for CS89x0 chipset based Ethernet cards. If you have a
network (Ethernet) card of this type, say Y and read the
@@ -1509,10 +1508,15 @@ config CS89x0
To compile this driver as a module, choose M here. The module
will be called cs89x0.
-config CS89x0_NONISA_IRQ
- def_bool y
- depends on CS89x0 != n
- depends on MACH_IXDP2351 || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440
+config CS89x0_PLATFORM
+ bool "CS89x0 platform driver support"
+ depends on CS89x0
+ help
+ Say Y to compile the cs890x0 driver as a platform driver. This
+ makes this driver suitable for use on certain evaluation boards
+ such as the IMX21ADS.
+
+ If you are unsure, say N.
config TC35815
tristate "TOSHIBA TC35815 Ethernet support"
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 068c356..3c53ab1 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -189,7 +189,7 @@ static struct devprobe2 isa_probes[] __initdata = {
#ifdef CONFIG_SEEQ8005
{seeq8005_probe, 0},
#endif
-#ifdef CONFIG_CS89x0
+#if defined(CONFIG_CS89x0) && !defined(CONFIG_CS89x0_PLATFORM)
{cs89x0_probe, 0},
#endif
#ifdef CONFIG_AT1700
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index 537a4b2..b7fb3bc 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -12,6 +12,14 @@
The author may be reached at nelson at crynwr.com, Crynwr
Software, 521 Pleasant Valley Rd., Potsdam, NY 13676
+Sources
+
+ Crynwr packet driver epktisa.
+
+ Crystal Semiconductor data sheets.
+
+
+
Changelog:
Mike Cruse : mcruse at cti-ltd.com
@@ -98,39 +106,14 @@
Domenico Andreoli : cavokz at gmail.com
: QQ2440 platform support
+ Jaccon Bastiaansen: jaccon.bastiaansen at gmail.com
+ : added platform driver support
*/
-/* Always include 'config.h' first in case the user wants to turn on
- or override something. */
-#include <linux/module.h>
-
-/*
- * Set this to zero to disable DMA code
- *
- * Note that even if DMA is turned off we still support the 'dma' and 'use_dma'
- * module options so we don't break any startup scripts.
- */
-#ifndef CONFIG_ISA_DMA_API
-#define ALLOW_DMA 0
-#else
-#define ALLOW_DMA 1
-#endif
-
-/*
- * Set this to zero to remove all the debug statements via
- * dead code elimination
- */
-#define DEBUGGING 1
-
-/*
- Sources:
-
- Crynwr packet driver epktisa.
-
- Crystal Semiconductor data sheets.
-
-*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/module.h>
+#include <linux/printk.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -147,21 +130,36 @@
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/gfp.h>
-
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
-#if ALLOW_DMA
+#include <linux/platform_device.h>
+#include "cs89x0.h"
+
+/*
+ * Set this to zero to disable DMA code
+ *
+ * Note that even if DMA is turned off we still support the 'dma' and 'use_dma'
+ * module options so we don't break any startup scripts.
+ */
+#ifndef CONFIG_ISA_DMA_API
+#define ALLOW_DMA 0
+#else
+#define ALLOW_DMA 1
#include <asm/dma.h>
#endif
-#include "cs89x0.h"
-
-static char version[] __initdata =
-"cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton\n";
+/*
+ * Set this to zero to remove all the debug statements via
+ * dead code elimination
+ */
+#define DEBUGGING 1
#define DRV_NAME "cs89x0"
+static char version[] =
+"cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton\n";
+
/* First, a few definitions that the brave might change.
A zero-terminated list of I/O addresses to be probed. Some special flags..
Addr & 1 = Read back the address port, look for signature and reset
@@ -173,22 +171,9 @@ static char version[] __initdata =
/* The cs8900 has 4 IRQ pins, software selectable. cs8900_irq_map maps
them to system IRQ numbers. This mapping is card specific and is set to
the configuration of the Cirrus Eval board for this chip. */
-#if defined(CONFIG_MACH_IXDP2351)
-static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
-static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0};
-#elif defined(CONFIG_ARCH_IXDP2X01)
-static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
-static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
-#elif defined(CONFIG_MACH_QQ2440)
-#include <mach/qq2440.h>
-static unsigned int netcard_portlist[] __used __initdata = { QQ2440_CS8900_VIRT_BASE + 0x300, 0 };
-static unsigned int cs8900_irq_map[] = { QQ2440_CS8900_IRQ, 0, 0, 0 };
-#elif defined(CONFIG_MACH_MX31ADS)
-#include <mach/board-mx31ads.h>
-static unsigned int netcard_portlist[] __used __initdata = {
- PBC_BASE_ADDRESS + PBC_CS8900A_IOBASE + 0x300, 0
-};
-static unsigned cs8900_irq_map[] = {EXPIO_INT_ENET_INT, 0, 0, 0};
+#if defined(CONFIG_CS89x0_PLATFORM)
+static unsigned int netcard_portlist[] __used __initdata = {0, 0};
+static unsigned int cs8900_irq_map[] = {0, 0, 0, 0};
#else
static unsigned int netcard_portlist[] __used __initdata =
{ 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
@@ -424,7 +409,7 @@ writereg(struct net_device *dev, u16 regno, u16 value)
writeword(dev->base_addr, DATA_PORT, value);
}
-static int __init
+static int
wait_eeprom_ready(struct net_device *dev)
{
int timeout = jiffies;
@@ -437,7 +422,7 @@ wait_eeprom_ready(struct net_device *dev)
return 0;
}
-static int __init
+static int
get_eeprom_data(struct net_device *dev, int off, int len, int *buffer)
{
int i;
@@ -455,7 +440,7 @@ get_eeprom_data(struct net_device *dev, int off, int len, int *buffer)
return 0;
}
-static int __init
+static int
get_eeprom_cksum(int off, int len, int *buffer)
{
int i, cksum;
@@ -503,7 +488,7 @@ static const struct net_device_ops net_ops = {
Return 0 on success.
*/
-static int __init
+static int
cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
{
struct net_local *lp = netdev_priv(dev);
@@ -529,9 +514,6 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
lp->force = g_cs89x0_media__force;
#endif
-#if defined(CONFIG_MACH_QQ2440)
- lp->force |= FORCE_RJ45 | FORCE_FULL;
-#endif
}
/* Grab the region so we can find another board if autoIRQ fails. */
@@ -737,7 +719,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
} else {
i = lp->isa_config & INT_NO_MASK;
if (lp->chip_type == CS8900) {
-#ifdef CONFIG_CS89x0_NONISA_IRQ
+#ifdef CONFIG_CS89x0_PLATFORM
i = cs8900_irq_map[0];
#else
/* Translate the IRQ using the IRQ mapping table. */
@@ -1228,7 +1210,7 @@ net_open(struct net_device *dev)
}
else
{
-#ifndef CONFIG_CS89x0_NONISA_IRQ
+#ifndef CONFIG_CS89x0_PLATFORM
if (((1 << dev->irq) & lp->irq_map) == 0) {
printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
dev->name, dev->irq, lp->irq_map);
@@ -1746,7 +1728,7 @@ static int set_mac_address(struct net_device *dev, void *p)
return 0;
}
-#ifdef MODULE
+#if defined(MODULE) && !defined(CONFIG_CS89x0_PLATFORM)
static struct net_device *dev_cs89x0;
@@ -1900,7 +1882,74 @@ cleanup_module(void)
release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
free_netdev(dev_cs89x0);
}
-#endif /* MODULE */
+#endif /* MODULE && !CONFIG_CS89x0_PLATFORM */
+
+#ifdef CONFIG_CS89x0_PLATFORM
+static int cs89x0_platform_probe(struct platform_device *pdev)
+{
+ struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+ struct resource *mem_res;
+ struct resource *irq_res;
+ int err;
+
+ if (!dev)
+ return -ENODEV;
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (mem_res == NULL || irq_res == NULL) {
+ pr_warning("memory and/or interrupt resource missing.\n");
+ err = -ENOENT;
+ goto out;
+ }
+
+ cs8900_irq_map[0] = irq_res->start;
+ err = cs89x0_probe1(dev, mem_res->start, 0);
+ if (err) {
+ pr_warning("no cs8900 or cs8920 detected.\n");
+ goto out;
+ }
+
+ platform_set_drvdata(pdev, dev);
+ return 0;
+out:
+ free_netdev(dev);
+ return err;
+}
+
+static int cs89x0_platform_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+
+ unregister_netdev(dev);
+ free_netdev(dev);
+ return 0;
+}
+
+static struct platform_driver cs89x0_platform_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = cs89x0_platform_probe,
+ .remove = cs89x0_platform_remove,
+};
+
+static int __init cs89x0_init(void)
+{
+ return platform_driver_register(&cs89x0_platform_driver);
+}
+
+module_init(cs89x0_init);
+
+static void __exit cs89x0_cleanup(void)
+{
+ platform_driver_unregister(&cs89x0_platform_driver);
+}
+
+module_exit(cs89x0_cleanup);
+
+#endif
/*
* Local variables:
--
1.7.1
^ permalink raw reply related
* [RFC PATCH 0/3] Add accurate boot timing to a Linux system
From: Simon Glass @ 2011-09-27 18:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E802F7D.9000006@parrot.com>
Hi Matthieu,
On Mon, Sep 26, 2011 at 12:53 AM, Matthieu CASTET
<matthieu.castet@parrot.com> wrote:
> Hi,
>
> Russell King - ARM Linux a ?crit :
>> On Fri, Sep 23, 2011 at 04:03:15PM -0700, Simon Glass wrote:
>>> An accurate timer is required to make the numbers meaningful. Many
>>> modern platforms have a microsecond timer. This patch set uses a
>>> function called timer_get_us() to read the timer.
>>
>> Not another 'get a time value' function. ?Why do we need soo many?
>> We have - at least:
>>
>> ktime_get (and various flavours of it)
>> do_gettimeofday
>> getnstimeofday
>> sched_clock
>>
>> Do we really need yet another one which will have to be multiplexed
>> amongst platforms, requiring scaling and so forth from whatever the
>> platform provides?
>>
>> Remember that ARM timers are virtually all MMIO mapped, which means
>> they don't work during early kernel bringup when the MMU mappings for
>> the hardware have not been setup. ?(That's the reason stuff like
>> sched_clock for printk doesn't work early.)
> Doesn't cortexA-8 (and A9 ?) have a cycle counter that can be read by
> coprocessor 15 ?
>
> Couldn't we use that counter for early stuff on those architectures ?
Yes we could, but we need to be careful that we use a 'time of day'
counter, not dependent on clock speed, CPU load and the like. See my
other email for what I see as the ideal timer. Obviously this will
have to be architecture-specific, but I hope for a simple fallback to
something available on all architectures, with perhaps the ability to
use better timers available on specific architectures which implement
them.
Regards,
Simon
>
>
> Matthieu
>
^ permalink raw reply
* [PATCH v3 5/6] OMAP: omap_device: Create a default omap_device_pm_latency
From: Kevin Hilman @ 2011-09-27 18:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110927173048.GM6324@atomide.com>
Tony Lindgren <tony@atomide.com> writes:
> * Benoit Cousson <b-cousson@ti.com> [110927 09:45]:
>> Most devices are using the same default omap_device_pm_latency structure
>> during device built. In order to avoid the duplication of the same
>> structure everywhere, add a default structure that will be used if
>> the device does not have an explicit one.
>>
>> Next patches will clean the duplicated structures.
>>
>> Signed-off-by: Benoit Cousson <b-cousson@ti.com>
>> Cc: Kevin Hilman <khilman@ti.com>
>> Cc: Paul Walmsley <paul@pwsan.com>
>> ---
>> arch/arm/plat-omap/omap_device.c | 19 ++++++++++++++++++-
>> 1 files changed, 18 insertions(+), 1 deletions(-)
>>
>> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
>> index f832f92..cd8d977 100644
>> --- a/arch/arm/plat-omap/omap_device.c
>> +++ b/arch/arm/plat-omap/omap_device.c
>> @@ -97,6 +97,14 @@
>> static int omap_device_register(struct platform_device *pdev);
>> static int omap_early_device_register(struct platform_device *pdev);
>>
>> +static struct omap_device_pm_latency omap_default_latency[] = {
>> + {
>> + .deactivate_func = omap_device_idle_hwmods,
>> + .activate_func = omap_device_enable_hwmods,
>> + .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
>> + }
>> +};
>> +
>> /* Private functions */
>
> Isn't this racey between devices if the latency values get adjusted
> automatically for each device?
A copy of this is made for each device (uses kmemdup later in the patch.)
Kevin
^ permalink raw reply
* [PATCH V2] Add CS890x0 ethernet controller support to the i.MX21ADS
From: Jaccon Bastiaansen @ 2011-09-27 18:31 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Jaccon Bastiaansen <jaccon.bastiaansen@gmail.com>
---
arch/arm/mach-imx/mach-mx21ads.c | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c
index 74ac889..62b4717 100644
--- a/arch/arm/mach-imx/mach-mx21ads.c
+++ b/arch/arm/mach-imx/mach-mx21ads.c
@@ -159,6 +159,26 @@ static struct platform_device mx21ads_nor_mtd_device = {
.resource = &mx21ads_flash_resource,
};
+static struct resource mx21ads_cs8900_resources[] = {
+ {
+ .start = (u32)MX21ADS_CS8900A_IOBASE_REG,
+ .end = (u32)MX21ADS_CS8900A_IOBASE_REG + 0x200000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX21ADS_CS8900A_IRQ,
+ .end = MX21ADS_CS8900A_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mx21ads_cs8900_device = {
+ .name = "cs89x0",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mx21ads_cs8900_resources),
+ .resource = mx21ads_cs8900_resources,
+};
+
static const struct imxuart_platform_data uart_pdata_rts __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -275,6 +295,7 @@ static void __init mx21ads_map_io(void)
static struct platform_device *platform_devices[] __initdata = {
&mx21ads_nor_mtd_device,
+ &mx21ads_cs8900_device
};
static void __init mx21ads_board_init(void)
--
1.7.1
^ permalink raw reply related
* [PATCH v3 0/3] Add support for tegra2 based ventana board
From: Peter De Schrijver @ 2011-09-27 18:35 UTC (permalink / raw)
To: linux-arm-kernel
This patch set adds support for the tegra2 based ventana development board.
Boot tested on ventana.
Peter De Schrijver (3):
arm/tegra: prepare Seaboard pinmux code for derived boards
arm/tegra: add support for ventana pinmuxing
arm/tegra: device tree support for ventana board
arch/arm/boot/dts/tegra-ventana.dts | 32 ++++++++++++++
arch/arm/mach-tegra/Kconfig | 6 +++
arch/arm/mach-tegra/Makefile | 1 +
arch/arm/mach-tegra/Makefile.boot | 1 +
arch/arm/mach-tegra/board-dt.c | 5 ++-
arch/arm/mach-tegra/board-seaboard-pinmux.c | 63 ++++++++++++++++++++++++---
6 files changed, 101 insertions(+), 7 deletions(-)
create mode 100644 arch/arm/boot/dts/tegra-ventana.dts
^ permalink raw reply
* [PATCH v3 1/3] arm/tegra: prepare Seaboard pinmux code for derived boards
From: Peter De Schrijver @ 2011-09-27 18:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317148524-28528-1-git-send-email-pdeschrijver@nvidia.com>
This patch splits out the common part of pinmux and GPIO initialization for
seaboard and derived boards. This code is based on work done by Jong Kim
<jongk@nvidia.com>.
Change-Id: I861db37c727a7118d38885c4bcb6f4acce3d4133
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
arch/arm/mach-tegra/board-seaboard-pinmux.c | 14 ++++++++++----
1 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-tegra/board-seaboard-pinmux.c b/arch/arm/mach-tegra/board-seaboard-pinmux.c
index 74f78b7..b31c765 100644
--- a/arch/arm/mach-tegra/board-seaboard-pinmux.c
+++ b/arch/arm/mach-tegra/board-seaboard-pinmux.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2010 NVIDIA Corporation
+ * Copyright (C) 2010,2011 NVIDIA Corporation
+ * Copyright (C) 2011 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -160,7 +161,7 @@ static __initdata struct tegra_pingroup_config seaboard_pinmux[] = {
-static struct tegra_gpio_table gpio_table[] = {
+static struct tegra_gpio_table common_gpio_table[] = {
{ .gpio = TEGRA_GPIO_SD2_CD, .enable = true },
{ .gpio = TEGRA_GPIO_SD2_WP, .enable = true },
{ .gpio = TEGRA_GPIO_SD2_POWER, .enable = true },
@@ -171,12 +172,17 @@ static struct tegra_gpio_table gpio_table[] = {
{ .gpio = TEGRA_GPIO_USB1, .enable = true },
};
-void __init seaboard_pinmux_init(void)
+static void __init seaboard_common_pinmux_init(void)
{
tegra_pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux));
tegra_drive_pinmux_config_table(seaboard_drive_pinmux,
ARRAY_SIZE(seaboard_drive_pinmux));
- tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
+ tegra_gpio_config(common_gpio_table, ARRAY_SIZE(common_gpio_table));
+}
+
+void __init seaboard_pinmux_init(void)
+{
+ seaboard_common_pinmux_init();
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH v3 2/3] arm/tegra: add support for ventana pinmuxing
From: Peter De Schrijver @ 2011-09-27 18:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317148524-28528-1-git-send-email-pdeschrijver@nvidia.com>
Add support for ventana pinmuxing as a seaboard derivative. This is a cut down
version of work done by Jong Kim <jongk@nvidia.com>.
Change-Id: I54bbf7a507dac193fa88f339d3e47f3d473dfc96
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
arch/arm/mach-tegra/Makefile | 1 +
arch/arm/mach-tegra/board-seaboard-pinmux.c | 49 +++++++++++++++++++++++++-
2 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index f11b910..91a07e1 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -31,6 +31,7 @@ obj-${CONFIG_MACH_SEABOARD} += board-seaboard-pinmux.o
obj-${CONFIG_MACH_TEGRA_DT} += board-dt.o
obj-${CONFIG_MACH_TEGRA_DT} += board-harmony-pinmux.o
+obj-${CONFIG_MACH_TEGRA_DT} += board-seaboard-pinmux.o
obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice.o
obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice-pinmux.o
diff --git a/arch/arm/mach-tegra/board-seaboard-pinmux.c b/arch/arm/mach-tegra/board-seaboard-pinmux.c
index b31c765..b62b04d 100644
--- a/arch/arm/mach-tegra/board-seaboard-pinmux.c
+++ b/arch/arm/mach-tegra/board-seaboard-pinmux.c
@@ -158,8 +158,26 @@ static __initdata struct tegra_pingroup_config seaboard_pinmux[] = {
{TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
};
-
-
+static __initdata struct tegra_pingroup_config ventana_pinmux[] = {
+ {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DDC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LPW0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LPW2, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LSC1, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LSCK, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSDA, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_PTA, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SLXK, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+};
static struct tegra_gpio_table common_gpio_table[] = {
{ .gpio = TEGRA_GPIO_SD2_CD, .enable = true },
@@ -172,6 +190,26 @@ static struct tegra_gpio_table common_gpio_table[] = {
{ .gpio = TEGRA_GPIO_USB1, .enable = true },
};
+static void __init update_pinmux(struct tegra_pingroup_config *newtbl, int size)
+{
+ int i, j;
+ struct tegra_pingroup_config *new_pingroup, *base_pingroup;
+
+ /* Update base seaboard pinmux table with secondary board
+ * specific pinmux table table.
+ */
+ for (i = 0; i < size; i++) {
+ new_pingroup = &newtbl[i];
+ for (j = 0; j < ARRAY_SIZE(seaboard_pinmux); j++) {
+ base_pingroup = &seaboard_pinmux[j];
+ if (new_pingroup->pingroup == base_pingroup->pingroup) {
+ *base_pingroup = *new_pingroup;
+ break;
+ }
+ }
+ }
+}
+
static void __init seaboard_common_pinmux_init(void)
{
tegra_pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux));
@@ -186,3 +224,10 @@ void __init seaboard_pinmux_init(void)
{
seaboard_common_pinmux_init();
}
+
+void __init ventana_pinmux_init(void)
+{
+ update_pinmux(ventana_pinmux, ARRAY_SIZE(ventana_pinmux));
+ seaboard_common_pinmux_init();
+}
+
--
1.7.0.4
^ permalink raw reply related
* [PATCH v3 3/3] arm/tegra: device tree support for ventana board
From: Peter De Schrijver @ 2011-09-27 18:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317148524-28528-1-git-send-email-pdeschrijver@nvidia.com>
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
arch/arm/boot/dts/tegra-ventana.dts | 32 ++++++++++++++++++++++++++++++++
arch/arm/mach-tegra/Kconfig | 6 ++++++
arch/arm/mach-tegra/Makefile.boot | 1 +
arch/arm/mach-tegra/board-dt.c | 5 ++++-
4 files changed, 43 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/boot/dts/tegra-ventana.dts
diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts
new file mode 100644
index 0000000..9b29a62
--- /dev/null
+++ b/arch/arm/boot/dts/tegra-ventana.dts
@@ -0,0 +1,32 @@
+/dts-v1/;
+
+/memreserve/ 0x1c000000 0x04000000;
+/include/ "tegra20.dtsi"
+
+/ {
+ model = "NVIDIA Tegra2 Ventana evaluation board";
+ compatible = "nvidia,ventana", "nvidia,tegra20";
+
+ chosen {
+ bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/ram rdinit=/sbin/init";
+ };
+
+ memory {
+ reg = < 0x00000000 0x40000000 >;
+ };
+
+ serial at 70006300 {
+ clock-frequency = < 216000000 >;
+ };
+
+ sdhci at c8000400 {
+ cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+ wp-gpios = <&gpio 57 0>; /* gpio PH1 */
+ power-gpios = <&gpio 155 0>; /* gpio PT3 */
+ };
+
+ sdhci at c8000600 {
+ power-gpios = <&gpio 70 0>; /* gpio PI6 */
+ support-8bit;
+ };
+};
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index d82ebab..91aff7c 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -69,6 +69,12 @@ config MACH_WARIO
help
Support for the Wario version of Seaboard
+config MACH_VENTANA
+ bool "Ventana board"
+ select MACH_TEGRA_DT
+ help
+ Support for the nVidia Ventana development platform
+
choice
prompt "Low-level debug console UART"
default TEGRA_DEBUG_UART_NONE
diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot
index 5e870d2..bd12c9f 100644
--- a/arch/arm/mach-tegra/Makefile.boot
+++ b/arch/arm/mach-tegra/Makefile.boot
@@ -4,3 +4,4 @@ initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000
dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb
dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb
+dtb-$(CONFIG_MACH_VENTANA) += tegra-ventana.dtb
diff --git a/arch/arm/mach-tegra/board-dt.c b/arch/arm/mach-tegra/board-dt.c
index 9f47e04..5885102 100644
--- a/arch/arm/mach-tegra/board-dt.c
+++ b/arch/arm/mach-tegra/board-dt.c
@@ -47,7 +47,7 @@
void harmony_pinmux_init(void);
void seaboard_pinmux_init(void);
-
+void ventana_pinmux_init(void);
struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL),
@@ -95,6 +95,8 @@ static void __init tegra_dt_init(void)
harmony_pinmux_init();
else if (of_machine_is_compatible("nvidia,seaboard"))
seaboard_pinmux_init();
+ else if (of_machine_is_compatible("nvidia,ventana"))
+ ventana_pinmux_init();
/*
* Finished with the static registrations now; fill in the missing
@@ -106,6 +108,7 @@ static void __init tegra_dt_init(void)
static const char * tegra_dt_board_compat[] = {
"nvidia,harmony",
"nvidia,seaboard",
+ "nvidia,ventana",
NULL
};
--
1.7.0.4
^ permalink raw reply related
* [PATCH v3 5/6] OMAP: omap_device: Create a default omap_device_pm_latency
From: Tony Lindgren @ 2011-09-27 18:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87hb3xzvmo.fsf@ti.com>
* Kevin Hilman <khilman@ti.com> [110927 10:56]:
> Tony Lindgren <tony@atomide.com> writes:
>
> > Isn't this racey between devices if the latency values get adjusted
> > automatically for each device?
>
> A copy of this is made for each device (uses kmemdup later in the patch.)
Oh ok, sorry for the noise.
Tony
^ permalink raw reply
* [RFC PATCH 0/3] Add accurate boot timing to a Linux system
From: Simon Glass @ 2011-09-27 18:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E820E4D.5050205@am.sony.com>
Hi Tim,
On Tue, Sep 27, 2011 at 10:56 AM, Tim Bird <tim.bird@am.sony.com> wrote:
> On 09/23/2011 04:03 PM, Simon Glass wrote:
>> This experimental patch set adds boot timing to a Linux system. The
>> timing starts with the boot loader and extends through the kernel into
>> user space to the completion of the boot process. The timing starts when
>> the system leaves reset, not later when the kernel starts.
>
> I would be very interested in this. ?This is something that
> would be very helpful, I believe, to assist with optimizing
> overall boot time.
Good.
>
>> Finally, in user space there is no kernel-blessed way to record
>> timestamps. One approach is to add lines to the init scripts like
>> 'cat /proc/uptime >/tmp/login_starts'.
>> This creates another place where
>> the boot timing tool must look for information.
>
> 'cat /proc/uptime >/dev/kmsg' (with printk timestamps on) is much
> better than the above, for this reason.
Yes, although this needs root access on my machine. Am hoping to have
something easily accessible from user space.
>
>> This Patchset
>> -------------
>> This patchset aims to unify timing in one place: a simple driver which
>> collects pre-kernel boot timestamps, adds its own as it boots, with
>> calls to bootstage_mark(), then allows user space (init, etc.) to add
>> more with 'echo "message" >>/sys/kernel/debug/bootstage/mask'.
>>
>> Finally it permits user space to access the full list of timestamps
>> with 'cat /sys/kernel/debug/bootstage/report', which has two columns:
>> the stage name and the timestamp:
>>
>> ? ? ? reset ? 0
>> ? ? ? arch_cpu_init-AVP ? ? ? 258902
>> ? ? ? arch_cpu_init-A9 ? ? ? ?263267
>> ? ? ? arch_cpu_init-done ? ? ?263312
>> ? ? ? board_init_f-start ? ? ?263314
>> ? ? ? board_init_r-start ? ? ?323671
>> ? ? ? main_loop ? ? ? 573008
> ...
>
> I would prefer the timestamp in the first column. ?Also, for consistency
> it would be good if it used the same format as printk timestamps:
> "[%5lu.%06lu]" with seconds and micro-seconds in the respective fields.
> Then, existing tools like scripts/show_delta and scripts/bootgraph.pl
> could work on this data as well.
Yes that makes sense, I will adjust it.
>
> Full micro-second granularity is not required, but it's nice to keep
> the format the same, whether the clock supports it or not.
Yes, and it's surprising how often microsecond accuracy is useful. For
example, recently I was looking at the impact of reduced
voltage/frequency early in boot on an ARM platform. The difference was
only a few ms, and the microsecond timer resolution helped a lot in
seeing the impact of these changes.
>
> Finally, is this work related at all to this:
> http://lists.denx.de/pipermail/u-boot/2011-September/099996.html
> Bootgraph.pl instrumentation support for UBoot
> ??
>
> Just wondering.
It is related in the sense that ideally all of this would come
together and play nicely. That's an interesting patch also, and there
are a few threads to tie together in U-Boot independently of the
kernel.
My original U-Boot patch set was here:
http://lists.denx.de/pipermail/u-boot/2011-May/092584.html
>
> Thanks - this looks like great stuff!
Thanks!
Regards,
Simon
> ?-- Tim
>
> =============================
> Tim Bird
> Architecture Group Chair, CE Workgroup of the Linux Foundation
> Senior Staff Engineer, Sony Network Entertainment
> =============================
>
>
^ permalink raw reply
* [PATCH 8/9] regulator: helper to extract regulator node based on supply name
From: Mark Brown @ 2011-09-27 18:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E81E281.505@ti.com>
On Tue, Sep 27, 2011 at 08:19:37PM +0530, Rajendra Nayak wrote:
> On Tuesday 27 September 2011 05:51 PM, Mark Brown wrote:
> >On Tue, Sep 27, 2011 at 03:42:51PM +0530, Rajendra Nayak wrote:
> >>+ if (!dev)
> >>+ return NULL;
> >So how do we handle CPUs? cpufreq is one of the most active users of
> >regulators...
> Hmm, never thought of it :(
> Maybe I should associate a supply name with all
> regulators and then lookup from the global registered
> list.
I'm not sure how this should work in a device tree world, I'd *hope*
we'd get a device tree node for the CPU and could then just make this a
regular consumer thing but then the cpufreq drivers would need to be
updated to make use of it. The only reason we allow null devices right
now is the fact that cpufreq doesn't have a struct device it can use.
> >>+ snprintf(prop_name, 32, "%s-supply", supply);
> >>+
> >>+ prop = of_get_property(dev->of_node, prop_name,&sz);
> >>+ if (!prop || sz< 4)
> >>+ return NULL;
> >sz< 4? Magic! :)
> Its the valid phandle size.
> I guess I need a sz != 4
I think we need an of_get_phandle(), it'd be clearer what the check is,
more type safe and would avoid needing to replicate the check.
^ permalink raw reply
* [PATCH V2 0/3] S5P64X0 PM Support
From: Abhilash Kesavan @ 2011-09-27 20:22 UTC (permalink / raw)
To: linux-arm-kernel
The patchset adds Power Mangement support for S5P64X0. The first
two patches lay the groundwork for adding PM support, while the
final patch adds the SoC specific PM code.
Changes since V1:
- Changed register naming as per User Manual.
- Dropped the pm-gpio warning patch as it will be taken care in the gpio
movement patch by Kukjin Kim.
- Used soc_is_* for differentiating between 6440 and 6450.
- Merged all the sleep files of S5P SoCs while leaving the S3C64XX sleep
code as is.
Abhilash Kesavan (3):
ARM: S5P: Make the common S5P PM code conditionally compile
ARM: S5P: Make the sleep code common for S5P series SoCs
ARM: S5P64X0: Add Power Management support
arch/arm/Kconfig | 2 +-
arch/arm/mach-exynos4/Kconfig | 4 +
arch/arm/mach-exynos4/Makefile | 2 +-
arch/arm/mach-s5p64x0/Kconfig | 4 +
arch/arm/mach-s5p64x0/Makefile | 1 +
arch/arm/mach-s5p64x0/include/mach/map.h | 1 +
arch/arm/mach-s5p64x0/include/mach/pm-core.h | 117 +++++++++++++
arch/arm/mach-s5p64x0/include/mach/regs-clock.h | 33 ++++
arch/arm/mach-s5p64x0/include/mach/regs-gpio.h | 19 ++
arch/arm/mach-s5p64x0/irq-eint.c | 2 +
arch/arm/mach-s5p64x0/irq-pm.c | 92 ++++++++++
arch/arm/mach-s5p64x0/pm.c | 204 +++++++++++++++++++++++
arch/arm/mach-s5pv210/Kconfig | 2 +
arch/arm/mach-s5pv210/Makefile | 2 +-
arch/arm/mach-s5pv210/sleep.S | 52 ------
arch/arm/plat-s5p/Kconfig | 12 ++
arch/arm/plat-s5p/Makefile | 4 +-
arch/arm/{mach-exynos4 => plat-s5p}/sleep.S | 13 +-
18 files changed, 500 insertions(+), 66 deletions(-)
create mode 100644 arch/arm/mach-s5p64x0/include/mach/pm-core.h
create mode 100644 arch/arm/mach-s5p64x0/irq-pm.c
create mode 100644 arch/arm/mach-s5p64x0/pm.c
delete mode 100644 arch/arm/mach-s5pv210/sleep.S
rename arch/arm/{mach-exynos4 => plat-s5p}/sleep.S (81%)
^ permalink raw reply
* [PATCH 1/3] ARM: S5P: Make the common S5P PM code conditionally compile
From: Abhilash Kesavan @ 2011-09-27 20:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317154964-22600-1-git-send-email-a.kesavan@samsung.com>
Pave the way for adding PM support on S5P64X0, which is more similar
to the S3C64XX series than the S5P series. Hence, the common pm code
(containing dummy functions) should not be used for S5P64X0.
Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
---
arch/arm/mach-exynos4/Kconfig | 2 ++
arch/arm/mach-s5pv210/Kconfig | 1 +
arch/arm/plat-s5p/Kconfig | 6 ++++++
arch/arm/plat-s5p/Makefile | 3 +--
4 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 3b594fe..7ed7d49 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -12,11 +12,13 @@ if ARCH_EXYNOS4
config CPU_EXYNOS4210
bool
select SAMSUNG_DMADEV
+ select S5P_PM if PM
help
Enable EXYNOS4210 CPU support
config SOC_EXYNOS4212
bool
+ select S5P_PM if PM
help
Enable EXYNOS4212 SoC support
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index ccef034..356aa75 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -14,6 +14,7 @@ config CPU_S5PV210
select SAMSUNG_DMADEV
select S5P_EXT_INT
select S5P_HRT
+ select S5P_PM if PM
help
Enable S5PV210 CPU support
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index f9241a7..53e6743 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -40,6 +40,12 @@ config S5P_HRT
help
Use the High Resolution timer support
+config S5P_PM
+ bool
+ help
+ Common code for power management support on S5P and newer SoCs
+ Note: Do not select this for S5P6440 and S5P6450.
+
comment "System MMU"
config S5P_SYSTEM_MMU
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index 1812019..755d7ac 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -20,8 +20,7 @@ obj-y += irq.o
obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o
obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o
-obj-$(CONFIG_PM) += pm.o
-obj-$(CONFIG_PM) += irq-pm.o
+obj-$(CONFIG_S5P_PM) += pm.o irq-pm.o
obj-$(CONFIG_S5P_HRT) += s5p-time.o
# devices
--
1.7.0.4
^ permalink raw reply related
* [PATCH 2/3] ARM: S5P: Make the sleep code common for S5P series SoCs
From: Abhilash Kesavan @ 2011-09-27 20:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317154964-22600-1-git-send-email-a.kesavan@samsung.com>
The sleep code for S5PV210 and EXYNOS4 are identical; moreover
S5p64X0 and S5PC100 for which support will be added soon can
use the same procedure. Create a common sleep code in the plat-s5p
directory so that it can be re-used.
Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
---
arch/arm/mach-exynos4/Kconfig | 2 +
arch/arm/mach-exynos4/Makefile | 2 +-
arch/arm/mach-s5pv210/Kconfig | 1 +
arch/arm/mach-s5pv210/Makefile | 2 +-
arch/arm/mach-s5pv210/sleep.S | 52 ---------------------------
arch/arm/plat-s5p/Kconfig | 6 +++
arch/arm/plat-s5p/Makefile | 1 +
arch/arm/{mach-exynos4 => plat-s5p}/sleep.S | 13 ++-----
8 files changed, 16 insertions(+), 63 deletions(-)
delete mode 100644 arch/arm/mach-s5pv210/sleep.S
rename arch/arm/{mach-exynos4 => plat-s5p}/sleep.S (81%)
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 7ed7d49..d440df9 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -13,12 +13,14 @@ config CPU_EXYNOS4210
bool
select SAMSUNG_DMADEV
select S5P_PM if PM
+ select S5P_SLEEP if PM
help
Enable EXYNOS4210 CPU support
config SOC_EXYNOS4212
bool
select S5P_PM if PM
+ select S5P_SLEEP if PM
help
Enable EXYNOS4212 SoC support
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index e19cd12..c8f68ab 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -16,7 +16,7 @@ obj-$(CONFIG_ARCH_EXYNOS4) += cpu.o init.o clock.o irq-combiner.o
obj-$(CONFIG_ARCH_EXYNOS4) += setup-i2c0.o irq-eint.o dma.o pmu.o
obj-$(CONFIG_CPU_EXYNOS4210) += clock-exynos4210.o
obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o
-obj-$(CONFIG_PM) += pm.o sleep.o
+obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 356aa75..a356e82 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -15,6 +15,7 @@ config CPU_S5PV210
select S5P_EXT_INT
select S5P_HRT
select S5P_PM if PM
+ select S5P_SLEEP if PM
help
Enable S5PV210 CPU support
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index ef7e466..009fbe5 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -14,7 +14,7 @@ obj- :=
obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o
obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o
-obj-$(CONFIG_PM) += pm.o sleep.o
+obj-$(CONFIG_PM) += pm.o
# machine support
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
deleted file mode 100644
index e3452cc..0000000
--- a/arch/arm/mach-s5pv210/sleep.S
+++ /dev/null
@@ -1,52 +0,0 @@
-/* linux/arch/arm/plat-s5p/sleep.S
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * S5PV210 power Manager (Suspend-To-RAM) support
- * Based on S3C2410 sleep code by:
- * Ben Dooks, (c) 2004 Simtec Electronics
- *
- * Based on PXA/SA1100 sleep code by:
- * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
- * Cliff Brake, (c) 2001
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/memory.h>
-
- .text
-
- /* sleep magic, to allow the bootloader to check for an valid
- * image to resume to. Must be the first word before the
- * s3c_cpu_resume entry.
- */
-
- .word 0x2bedf00d
-
- /* s3c_cpu_resume
- *
- * resume code entry for bootloader to call
- *
- * we must put this code here in the data segment as we have no
- * other way of restoring the stack pointer after sleep, and we
- * must not write to the code segment (code is read-only)
- */
-
-ENTRY(s3c_cpu_resume)
- b cpu_resume
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index 53e6743..7b9dada 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -54,6 +54,12 @@ config S5P_SYSTEM_MMU
help
Say Y here if you want to enable System MMU
+config S5P_SLEEP
+ bool
+ help
+ Internal config node to apply common S5P sleep management code.
+ Can be selected by S5P and newer SoCs with similar sleep procedure.
+
config S5P_DEV_FIMC0
bool
help
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index 755d7ac..06401dc 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o
obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o
obj-$(CONFIG_S5P_PM) += pm.o irq-pm.o
+obj-$(CONFIG_S5P_SLEEP) += sleep.o
obj-$(CONFIG_S5P_HRT) += s5p-time.o
# devices
diff --git a/arch/arm/mach-exynos4/sleep.S b/arch/arm/plat-s5p/sleep.S
similarity index 81%
rename from arch/arm/mach-exynos4/sleep.S
rename to arch/arm/plat-s5p/sleep.S
index 0984078..0fd591b 100644
--- a/arch/arm/mach-exynos4/sleep.S
+++ b/arch/arm/plat-s5p/sleep.S
@@ -1,15 +1,11 @@
-/* linux/arch/arm/mach-exynos4/sleep.S
+/* linux/arch/arm/plat-s5p/sleep.S
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
- * EXYNOS4210 power Manager (Suspend-To-RAM) support
- * Based on S3C2410 sleep code by:
- * Ben Dooks, (c) 2004 Simtec Electronics
- *
- * Based on PXA/SA1100 sleep code by:
- * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
- * Cliff Brake, (c) 2001
+ * Common S5P Sleep Code
+ * Based on S3C64XX sleep code by:
+ * Ben Dooks, (c) 2008 Simtec Electronics
*
* 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
@@ -28,7 +24,6 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include <asm/memory.h>
.text
--
1.7.0.4
^ permalink raw reply related
* [PATCH 3/3] ARM: S5P64X0: Add Power Management support
From: Abhilash Kesavan @ 2011-09-27 20:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317154964-22600-1-git-send-email-a.kesavan@samsung.com>
Add suspend-to-ram support for SMDK6440/50
Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
---
arch/arm/Kconfig | 2 +-
arch/arm/mach-s5p64x0/Kconfig | 4 +
arch/arm/mach-s5p64x0/Makefile | 1 +
arch/arm/mach-s5p64x0/include/mach/map.h | 1 +
arch/arm/mach-s5p64x0/include/mach/pm-core.h | 117 +++++++++++++
arch/arm/mach-s5p64x0/include/mach/regs-clock.h | 33 ++++
arch/arm/mach-s5p64x0/include/mach/regs-gpio.h | 19 ++
arch/arm/mach-s5p64x0/irq-eint.c | 2 +
arch/arm/mach-s5p64x0/irq-pm.c | 92 ++++++++++
arch/arm/mach-s5p64x0/pm.c | 204 +++++++++++++++++++++++
10 files changed, 474 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/mach-s5p64x0/include/mach/pm-core.h
create mode 100644 arch/arm/mach-s5p64x0/irq-pm.c
create mode 100644 arch/arm/mach-s5p64x0/pm.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 42401da..4d61466 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2079,7 +2079,7 @@ menu "Power management options"
source "kernel/power/Kconfig"
config ARCH_SUSPEND_POSSIBLE
- depends on !ARCH_S5P64X0 && !ARCH_S5PC100
+ depends on !ARCH_S5PC100
depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \
CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE
def_bool y
diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
index 9527ed2..15cea9c 100644
--- a/arch/arm/mach-s5p64x0/Kconfig
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -11,6 +11,8 @@ config CPU_S5P6440
bool
select SAMSUNG_DMADEV
select S5P_HRT
+ select S5P_SLEEP if PM
+ select SAMSUNG_WAKEMASK if PM
help
Enable S5P6440 CPU support
@@ -18,6 +20,8 @@ config CPU_S5P6450
bool
select SAMSUNG_DMADEV
select S5P_HRT
+ select S5P_SLEEP if PM
+ select SAMSUNG_WAKEMASK if PM
help
Enable S5P6450 CPU support
diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile
index 5b94955..f4bafbb 100644
--- a/arch/arm/mach-s5p64x0/Makefile
+++ b/arch/arm/mach-s5p64x0/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o
obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o irq-eint.o
obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o
obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o
+obj-$(CONFIG_PM) += pm.o irq-pm.o
# machine support
diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h
index 95c9125..6138f7c 100644
--- a/arch/arm/mach-s5p64x0/include/mach/map.h
+++ b/arch/arm/mach-s5p64x0/include/mach/map.h
@@ -85,5 +85,6 @@
#define S5P_PA_UART5 S5P6450_PA_UART(5)
#define S5P_SZ_UART SZ_256
+#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/pm-core.h b/arch/arm/mach-s5p64x0/include/mach/pm-core.h
new file mode 100644
index 0000000..e52f754
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/pm-core.h
@@ -0,0 +1,117 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/pm-core.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - PM core support for arch/arm/plat-samsung/pm.c
+ *
+ * Based on PM core support for S3C64XX by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <mach/regs-gpio.h>
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+ u32 tmp = __raw_readl(S5P64X0_CLK_GATE_PCLK);
+
+ /*
+ * As a note, since the S5P64X0 UARTs generally have multiple
+ * clock sources, we simply enable PCLK at the moment and hope
+ * that the resume settings for the UART are suitable for the
+ * use with PCLK.
+ */
+ tmp |= S5P64X0_CLK_GATE_PCLK_UART0;
+ tmp |= S5P64X0_CLK_GATE_PCLK_UART1;
+ tmp |= S5P64X0_CLK_GATE_PCLK_UART2;
+ tmp |= S5P64X0_CLK_GATE_PCLK_UART3;
+
+ __raw_writel(tmp, S5P64X0_CLK_GATE_PCLK);
+ udelay(10);
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+ /* VIC should have already been taken care of */
+
+ /* clear any pending EINT0 interrupts */
+ __raw_writel(__raw_readl(S5P64X0_EINT0PEND), S5P64X0_EINT0PEND);
+}
+
+static inline void s3c_pm_arch_stop_clocks(void) { }
+static inline void s3c_pm_arch_show_resume_irqs(void) { }
+
+/*
+ * make these defines, we currently do not have any need to change
+ * the IRQ wake controls depending on the CPU we are running on
+ */
+#define s3c_irqwake_eintallow ((1 << 16) - 1)
+#define s3c_irqwake_intallow (~0)
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+ struct pm_uart_save *save)
+{
+ u32 ucon = __raw_readl(regs + S3C2410_UCON);
+ u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK;
+ u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK;
+ u32 new_ucon;
+ u32 delta;
+
+ /*
+ * S5P64X0 UART blocks only support level interrupts, so ensure that
+ * when we restore unused UART blocks we force the level interrupt
+ * settings.
+ */
+ save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL;
+
+ /*
+ * We have a constraint on changing the clock type of the UART
+ * between UCLKx and PCLK, so ensure that when we restore UCON
+ * that the CLK field is correctly modified if the bootloader
+ * has changed anything.
+ */
+ if (ucon_clk != save_clk) {
+ new_ucon = save->ucon;
+ delta = ucon_clk ^ save_clk;
+
+ /*
+ * change from UCLKx => wrong PCLK,
+ * either UCLK can be tested for by a bit-test
+ * with UCLK0
+ */
+ if (ucon_clk & S3C6400_UCON_UCLK0 &&
+ !(save_clk & S3C6400_UCON_UCLK0) &&
+ delta & S3C6400_UCON_PCLK2) {
+ new_ucon &= ~S3C6400_UCON_UCLK0;
+ } else if (delta == S3C6400_UCON_PCLK2) {
+ /*
+ * as a precaution, don't change from
+ * PCLK2 => PCLK or vice-versa
+ */
+ new_ucon ^= S3C6400_UCON_PCLK2;
+ }
+
+ S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n",
+ ucon, new_ucon, save->ucon);
+ save->ucon = new_ucon;
+ }
+}
+
+static inline void s3c_pm_restored_gpios(void)
+{
+ /* ensure sleep mode has been cleared from the system */
+ __raw_writel(0, S5P64X0_SLPEN);
+}
+
+static inline void samsung_pm_saved_gpios(void)
+{
+ /*
+ * turn on the sleep mode and keep it there, as it seems that during
+ * suspend the xCON registers get re-set and thus you can end up with
+ * problems between going to sleep and resuming.
+ */
+ __raw_writel(S5P64X0_SLPEN_USE_xSLP, S5P64X0_SLPEN);
+}
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
index a133f22..bd91112 100644
--- a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
@@ -41,17 +41,50 @@
#define S5P6450_DPLL_CON S5P_CLKREG(0x50)
#define S5P6450_DPLL_CON_K S5P_CLKREG(0x54)
+#define S5P64X0_AHB_CON0 S5P_CLKREG(0x100)
#define S5P64X0_CLK_SRC1 S5P_CLKREG(0x10C)
#define S5P64X0_SYS_ID S5P_CLKREG(0x118)
#define S5P64X0_SYS_OTHERS S5P_CLKREG(0x11C)
#define S5P64X0_PWR_CFG S5P_CLKREG(0x804)
+#define S5P64X0_EINT_WAKEUP_MASK S5P_CLKREG(0x808)
+#define S5P64X0_SLEEP_CFG S5P_CLKREG(0x818)
+#define S5P64X0_PWR_STABLE S5P_CLKREG(0x828)
+
#define S5P64X0_OTHERS S5P_CLKREG(0x900)
+#define S5P64X0_WAKEUP_STAT S5P_CLKREG(0x908)
+
+#define S5P64X0_INFORM0 S5P_CLKREG(0xA00)
#define S5P64X0_CLKDIV0_HCLK_SHIFT (8)
#define S5P64X0_CLKDIV0_HCLK_MASK (0xF << S5P64X0_CLKDIV0_HCLK_SHIFT)
+/* HCLK GATE Registers */
+#define S5P64X0_CLK_GATE_HCLK1_FIMGVG (1 << 2)
+#define S5P64X0_CLK_GATE_SCLK1_FIMGVG (1 << 2)
+
+/* PCLK GATE Registers */
+#define S5P64X0_CLK_GATE_PCLK_UART3 (1 << 4)
+#define S5P64X0_CLK_GATE_PCLK_UART2 (1 << 3)
+#define S5P64X0_CLK_GATE_PCLK_UART1 (1 << 2)
+#define S5P64X0_CLK_GATE_PCLK_UART0 (1 << 1)
+
+#define S5P64X0_PWR_CFG_MMC1_DISABLE (1 << 15)
+#define S5P64X0_PWR_CFG_MMC0_DISABLE (1 << 14)
+#define S5P64X0_PWR_CFG_RTC_TICK_DISABLE (1 << 11)
+#define S5P64X0_PWR_CFG_RTC_ALRM_DISABLE (1 << 10)
+#define S5P64X0_PWR_CFG_WFI_MASK (3 << 5)
+#define S5P64X0_PWR_CFG_WFI_SLEEP (3 << 5)
+
+#define S5P64X0_SLEEP_CFG_OSC_EN (1 << 0)
+
+#define S5P64X0_PWR_STABLE_PWR_CNT_VAL4 (4 << 0)
+
+#define S5P6450_OTHERS_DISABLE_INT (1 << 31)
+#define S5P64X0_OTHERS_RET_UART (1 << 26)
+#define S5P64X0_OTHERS_RET_MMC1 (1 << 25)
+#define S5P64X0_OTHERS_RET_MMC0 (1 << 24)
#define S5P64X0_OTHERS_USB_SIG_MASK (1 << 16)
/* Compatibility defines */
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
index 6ce2547..27a2230 100644
--- a/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
@@ -34,14 +34,33 @@
#define S5P6450_GPQ_BASE (S5P_VA_GPIO + 0x0180)
#define S5P6450_GPS_BASE (S5P_VA_GPIO + 0x0300)
+#define S5P64X0_SPCON0 (S5P_VA_GPIO + 0x1A0)
+#define S5P64X0_SPCON1 (S5P_VA_GPIO + 0x2B0)
+
+#define S5P64X0_MEM0CONSLP0 (S5P_VA_GPIO + 0x1C0)
+#define S5P64X0_MEM0CONSLP1 (S5P_VA_GPIO + 0x1C4)
+#define S5P64X0_MEM0DRVCON (S5P_VA_GPIO + 0x1D0)
+#define S5P64X0_MEM1DRVCON (S5P_VA_GPIO + 0x1D4)
+
+#define S5P64X0_EINT12CON (S5P_VA_GPIO + 0x200)
+#define S5P64X0_EINT12FLTCON (S5P_VA_GPIO + 0x220)
+#define S5P64X0_EINT12MASK (S5P_VA_GPIO + 0x240)
+
/* External interrupt control registers for group0 */
#define EINT0CON0_OFFSET (0x900)
+#define EINT0FLTCON0_OFFSET (0x910)
+#define EINT0FLTCON1_OFFSET (0x914)
#define EINT0MASK_OFFSET (0x920)
#define EINT0PEND_OFFSET (0x924)
#define S5P64X0_EINT0CON0 (S5P_VA_GPIO + EINT0CON0_OFFSET)
+#define S5P64X0_EINT0FLTCON0 (S5P_VA_GPIO + EINT0FLTCON0_OFFSET)
+#define S5P64X0_EINT0FLTCON1 (S5P_VA_GPIO + EINT0FLTCON1_OFFSET)
#define S5P64X0_EINT0MASK (S5P_VA_GPIO + EINT0MASK_OFFSET)
#define S5P64X0_EINT0PEND (S5P_VA_GPIO + EINT0PEND_OFFSET)
+#define S5P64X0_SLPEN (S5P_VA_GPIO + 0x930)
+#define S5P64X0_SLPEN_USE_xSLP (1 << 0)
+
#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-s5p64x0/irq-eint.c b/arch/arm/mach-s5p64x0/irq-eint.c
index 494e1a8..275dc74 100644
--- a/arch/arm/mach-s5p64x0/irq-eint.c
+++ b/arch/arm/mach-s5p64x0/irq-eint.c
@@ -20,6 +20,7 @@
#include <plat/cpu.h>
#include <plat/regs-irqtype.h>
#include <plat/gpio-cfg.h>
+#include <plat/pm.h>
#include <mach/regs-gpio.h>
#include <mach/regs-clock.h>
@@ -134,6 +135,7 @@ static int s5p64x0_alloc_gc(void)
ct->chip.irq_mask = irq_gc_mask_set_bit;
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
ct->chip.irq_set_type = s5p64x0_irq_eint_set_type;
+ ct->chip.irq_set_wake = s3c_irqext_wake;
ct->regs.ack = EINT0PEND_OFFSET;
ct->regs.mask = EINT0MASK_OFFSET;
irq_setup_generic_chip(gc, IRQ_MSK(16), IRQ_GC_INIT_MASK_CACHE,
diff --git a/arch/arm/mach-s5p64x0/irq-pm.c b/arch/arm/mach-s5p64x0/irq-pm.c
new file mode 100644
index 0000000..3e6f245
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/irq-pm.c
@@ -0,0 +1,92 @@
+/* linux/arch/arm/mach-s5p64x0/irq-pm.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - Interrupt handling Power Management
+ *
+ * Based on arch/arm/mach-s3c64xx/irq-pm.c by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <plat/regs-serial.h>
+#include <plat/pm.h>
+
+#include <mach/regs-gpio.h>
+
+static struct sleep_save irq_save[] = {
+ SAVE_ITEM(S5P64X0_EINT0CON0),
+ SAVE_ITEM(S5P64X0_EINT0FLTCON0),
+ SAVE_ITEM(S5P64X0_EINT0FLTCON1),
+ SAVE_ITEM(S5P64X0_EINT0MASK),
+};
+
+static struct irq_grp_save {
+ u32 con;
+ u32 fltcon;
+ u32 mask;
+} eint_grp_save[4];
+
+static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS];
+
+static int s5p64x0_irq_pm_suspend(void)
+{
+ struct irq_grp_save *grp = eint_grp_save;
+ int i;
+
+ S3C_PMDBG("%s: suspending IRQs\n", __func__);
+
+ s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+
+ for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
+ irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM);
+
+ for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
+ grp->con = __raw_readl(S5P64X0_EINT12CON + (i * 4));
+ grp->mask = __raw_readl(S5P64X0_EINT12MASK + (i * 4));
+ grp->fltcon = __raw_readl(S5P64X0_EINT12FLTCON + (i * 4));
+ }
+
+ return 0;
+}
+
+static void s5p64x0_irq_pm_resume(void)
+{
+ struct irq_grp_save *grp = eint_grp_save;
+ int i;
+
+ S3C_PMDBG("%s: resuming IRQs\n", __func__);
+
+ s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+
+ for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
+ __raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM);
+
+ for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
+ __raw_writel(grp->con, S5P64X0_EINT12CON + (i * 4));
+ __raw_writel(grp->mask, S5P64X0_EINT12MASK + (i * 4));
+ __raw_writel(grp->fltcon, S5P64X0_EINT12FLTCON + (i * 4));
+ }
+
+ S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
+}
+
+static struct syscore_ops s5p64x0_irq_syscore_ops = {
+ .suspend = s5p64x0_irq_pm_suspend,
+ .resume = s5p64x0_irq_pm_resume,
+};
+
+static int __init s5p64x0_syscore_init(void)
+{
+ register_syscore_ops(&s5p64x0_irq_syscore_ops);
+
+ return 0;
+}
+core_initcall(s5p64x0_syscore_init);
diff --git a/arch/arm/mach-s5p64x0/pm.c b/arch/arm/mach-s5p64x0/pm.c
new file mode 100644
index 0000000..6992724
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/pm.c
@@ -0,0 +1,204 @@
+/* linux/arch/arm/mach-s5p64x0/pm.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 Power Management Support
+ *
+ * Based on arch/arm/mach-s3c64xx/pm.c by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/suspend.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/regs-timer.h>
+#include <plat/wakeup-mask.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+
+static struct sleep_save s5p64x0_core_save[] = {
+ SAVE_ITEM(S5P64X0_APLL_CON),
+ SAVE_ITEM(S5P64X0_MPLL_CON),
+ SAVE_ITEM(S5P64X0_EPLL_CON),
+ SAVE_ITEM(S5P64X0_EPLL_CON_K),
+ SAVE_ITEM(S5P64X0_CLK_SRC0),
+ SAVE_ITEM(S5P64X0_CLK_SRC1),
+ SAVE_ITEM(S5P64X0_CLK_DIV0),
+ SAVE_ITEM(S5P64X0_CLK_DIV1),
+ SAVE_ITEM(S5P64X0_CLK_DIV2),
+ SAVE_ITEM(S5P64X0_CLK_DIV3),
+ SAVE_ITEM(S5P64X0_CLK_GATE_MEM0),
+ SAVE_ITEM(S5P64X0_CLK_GATE_HCLK1),
+ SAVE_ITEM(S5P64X0_CLK_GATE_SCLK1),
+};
+
+static struct sleep_save s5p64x0_misc_save[] = {
+ SAVE_ITEM(S5P64X0_AHB_CON0),
+ SAVE_ITEM(S5P64X0_SPCON0),
+ SAVE_ITEM(S5P64X0_SPCON1),
+ SAVE_ITEM(S5P64X0_MEM0CONSLP0),
+ SAVE_ITEM(S5P64X0_MEM0CONSLP1),
+ SAVE_ITEM(S5P64X0_MEM0DRVCON),
+ SAVE_ITEM(S5P64X0_MEM1DRVCON),
+
+ SAVE_ITEM(S3C64XX_TINT_CSTAT),
+};
+
+/* DPLL is present only in S5P6450 */
+static struct sleep_save s5p6450_core_save[] = {
+ SAVE_ITEM(S5P6450_DPLL_CON),
+ SAVE_ITEM(S5P6450_DPLL_CON_K),
+};
+
+void s3c_pm_configure_extint(void)
+{
+ __raw_writel(s3c_irqwake_eintmask, S5P64X0_EINT_WAKEUP_MASK);
+}
+
+void s3c_pm_restore_core(void)
+{
+ __raw_writel(0, S5P64X0_EINT_WAKEUP_MASK);
+
+ s3c_pm_do_restore_core(s5p64x0_core_save,
+ ARRAY_SIZE(s5p64x0_core_save));
+
+ if (soc_is_s5p6450())
+ s3c_pm_do_restore_core(s5p6450_core_save,
+ ARRAY_SIZE(s5p6450_core_save));
+
+ s3c_pm_do_restore(s5p64x0_misc_save, ARRAY_SIZE(s5p64x0_misc_save));
+}
+
+void s3c_pm_save_core(void)
+{
+ s3c_pm_do_save(s5p64x0_misc_save, ARRAY_SIZE(s5p64x0_misc_save));
+
+ if (soc_is_s5p6450())
+ s3c_pm_do_save(s5p6450_core_save,
+ ARRAY_SIZE(s5p6450_core_save));
+
+ s3c_pm_do_save(s5p64x0_core_save, ARRAY_SIZE(s5p64x0_core_save));
+}
+
+static int s5p64x0_cpu_suspend(unsigned long arg)
+{
+ unsigned long tmp = 0;
+
+ /*
+ * Issue the standby signal into the pm unit. Note, we
+ * issue a write-buffer drain just in case.
+ */
+ asm("b 1f\n\t"
+ ".align 5\n\t"
+ "1:\n\t"
+ "mcr p15, 0, %0, c7, c10, 5\n\t"
+ "mcr p15, 0, %0, c7, c10, 4\n\t"
+ "mcr p15, 0, %0, c7, c0, 4" : : "r" (tmp));
+
+ /* we should never get past here */
+ panic("sleep resumed to originator?");
+}
+
+/* mapping of interrupts to parts of the wakeup mask */
+static struct samsung_wakeup_mask s5p64x0_wake_irqs[] = {
+ { .irq = IRQ_RTC_ALARM, .bit = S5P64X0_PWR_CFG_RTC_ALRM_DISABLE, },
+ { .irq = IRQ_RTC_TIC, .bit = S5P64X0_PWR_CFG_RTC_TICK_DISABLE, },
+ { .irq = IRQ_HSMMC0, .bit = S5P64X0_PWR_CFG_MMC0_DISABLE, },
+ { .irq = IRQ_HSMMC1, .bit = S5P64X0_PWR_CFG_MMC1_DISABLE, },
+};
+
+static void s5p64x0_pm_prepare(void)
+{
+ u32 tmp;
+
+ samsung_sync_wakemask(S5P64X0_PWR_CFG,
+ s5p64x0_wake_irqs, ARRAY_SIZE(s5p64x0_wake_irqs));
+
+ /* store the resume address in INFORM0 register */
+ __raw_writel(virt_to_phys(s3c_cpu_resume), S5P64X0_INFORM0);
+
+ /* setup clock gating for FIMGVG block */
+ __raw_writel((__raw_readl(S5P64X0_CLK_GATE_HCLK1) | \
+ (S5P64X0_CLK_GATE_HCLK1_FIMGVG)), S5P64X0_CLK_GATE_HCLK1);
+ __raw_writel((__raw_readl(S5P64X0_CLK_GATE_SCLK1) | \
+ (S5P64X0_CLK_GATE_SCLK1_FIMGVG)), S5P64X0_CLK_GATE_SCLK1);
+
+ /* Configure the stabilization counter with wait time required */
+ __raw_writel(S5P64X0_PWR_STABLE_PWR_CNT_VAL4, S5P64X0_PWR_STABLE);
+
+ /* set WFI to SLEEP mode configuration */
+ tmp = __raw_readl(S5P64X0_SLEEP_CFG);
+ tmp &= ~(S5P64X0_SLEEP_CFG_OSC_EN);
+ __raw_writel(tmp, S5P64X0_SLEEP_CFG);
+
+ tmp = __raw_readl(S5P64X0_PWR_CFG);
+ tmp &= ~(S5P64X0_PWR_CFG_WFI_MASK);
+ tmp |= S5P64X0_PWR_CFG_WFI_SLEEP;
+ __raw_writel(tmp, S5P64X0_PWR_CFG);
+
+ /*
+ * set OTHERS register to disable interrupt before going to
+ * sleep. This bit is present only in S5P6450, it is reserved
+ * in S5P6440.
+ */
+ if (soc_is_s5p6450()) {
+ tmp = __raw_readl(S5P64X0_OTHERS);
+ tmp |= S5P6450_OTHERS_DISABLE_INT;
+ __raw_writel(tmp, S5P64X0_OTHERS);
+ }
+
+ /* ensure previous wakeup state is cleared before sleeping */
+ __raw_writel(__raw_readl(S5P64X0_WAKEUP_STAT), S5P64X0_WAKEUP_STAT);
+
+}
+
+static int s5p64x0_pm_add(struct sys_device *sysdev)
+{
+ pm_cpu_prep = s5p64x0_pm_prepare;
+ pm_cpu_sleep = s5p64x0_cpu_suspend;
+ pm_uart_udivslot = 1;
+
+ return 0;
+}
+
+static struct sysdev_driver s5p64x0_pm_driver = {
+ .add = s5p64x0_pm_add,
+};
+
+static __init int s5p64x0_pm_drvinit(void)
+{
+ s3c_pm_init();
+
+ return sysdev_driver_register(&s5p64x0_sysclass, &s5p64x0_pm_driver);
+}
+arch_initcall(s5p64x0_pm_drvinit);
+
+static void s5p64x0_pm_resume(void)
+{
+ u32 tmp;
+
+ tmp = __raw_readl(S5P64X0_OTHERS);
+ tmp |= (S5P64X0_OTHERS_RET_MMC0 | S5P64X0_OTHERS_RET_MMC1 | \
+ S5P64X0_OTHERS_RET_UART);
+ __raw_writel(tmp , S5P64X0_OTHERS);
+}
+
+static struct syscore_ops s5p64x0_pm_syscore_ops = {
+ .resume = s5p64x0_pm_resume,
+};
+
+static __init int s5p64x0_pm_syscore_init(void)
+{
+ register_syscore_ops(&s5p64x0_pm_syscore_ops);
+
+ return 0;
+}
+arch_initcall(s5p64x0_pm_syscore_init);
--
1.7.0.4
^ permalink raw reply related
* Porting linux to Stellaris Cortex-M3
From: Russell King - ARM Linux @ 2011-09-27 20:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAH8SYHBFgkp47vf97qC_pseBOKNMrqVMj9sddjzUg1xjWpg6xw@mail.gmail.com>
On Tue, Sep 27, 2011 at 09:54:18AM -0300, Fernando Endo wrote:
> This is the log that I got with printascii bypassing printk:
>
> <5>Linux version 2.6.33-arm1 (fernando at fernando-POS-MIG31AG) (gcc
> version 4.5.2 (Sourcery G++ Lite 2011.03-41) ) #127 Tue Sep 27
> 09:14:21 BRT 2011
> CPU: ARMv7-M Processor [412fc230] revision 0 (ARMv?(11)M)
> CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
> Machine: Stellaris LM3S9B96
> <7>On node 0 totalpages: 2048
> <7>free_area_init_node: node 0, pgdat 600de1e0, node_mem_map 600f6000
> <7> ?DMA zone: 16 pages used for memmap
> <7> ?DMA zone: 0 pages reserved
> <7> ?DMA zone: 2032 pages, LIFO batch:0
> Built 1 zonelists in Zone order, mobility grouping off. ?Total pages: 2032
> <5>Kernel command line: init=/bin/busybox console=ttyS mem=8M
> <6>PID hash table entries: 32 (order: -5, 128 bytes)
> <6>Dentry cache hash table entries: 1024 (order: 0, 4096 bytes)
> <6>Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
> <6>Memory: 8MB = 8MB total
> <5>Memory: 7168k/7168k available, 1024k reserved, 0K highmem
> <5>Virtual kernel memory layout:
> ? ?vector ?: 0x00000000 - 0x00001000 ? ( ? 4 kB)
> ? ?fixmap ?: 0xfff00000 - 0xfffe0000 ? ( 896 kB)
> ? ?vmalloc : 0x00000000 - 0xffffffff ? (4095 MB)
> ? ?lowmem ?: 0x60000000 - 0x60800000 ? ( ? 8 MB)
> ? ?modules : 0x60000000 - 0x60800000 ? ( ? 8 MB)
> ? ? ?.init : 0x60008000 - 0x6002f000 ? ( 156 kB)
> ? ? ?.text : 0x6002f000 - 0x600cb000 ? ( 624 kB)
> ? ? ?.data : 0x600d6000 - 0x600deb40 ? ( ?35 kB)
> <6>Hierarchical RCU implementation.
> <6>NR_IRQS:54
> <6>console [ttyS0] enabled
> <6>Calibrating delay loop... <c>3.82 BogoMIPS (lpj=19136)
> Mount-cache hash table entries: 512
> <6>Switching to clocksource timer3
> <6>ttyS0 at MMIO 0x4000c000 (irq = 5) is a LM3S9B96 UARTx Port
> <6>Freeing init memory: 156K
> <3>BUG: scheduling while atomic: init/1/0xffff0003
> [<60032b6d>] (unwind_backtrace+0x1/0x88) from [<600a1379>] (dump_stack+0xd/0x10)
> [<600a1379>] (dump_stack+0xd/0x10) from [<60034ea5>] (__schedule_bug+0x35/0x40)
> [<60034ea5>] (__schedule_bug+0x35/0x40) from [<600a17b1>] (schedule+0x2d1/0x2f4)
> [<600a17b1>] (schedule+0x2d1/0x2f4) from [<6002f791>] (ret_slow_syscall+0x1/0xc)
Hmm, this doesn't look good. What this is showing is that it's the
call to schedule() in the code dealing with returning to userspace.
The preempt count shouldn't be this wrong here - it suggests that
something is returning with wrong preempt status.
The problem is it's not possible at this point to work out from the
information you've supplied whether it's a data abort, prefetch abort,
or SWI (SVC) call (and actually we don't have any tracking of that.)
If I had to guess I'd suggest that there was something fishy with
the IRQ handling - but without knowing what mods you've made to the
stock kernel, that's about as much speculation that I can give.
^ permalink raw reply
* [PATCH 1/2] ARM: vic: device tree binding
From: Grant Likely @ 2011-09-27 21:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317125802-14386-1-git-send-email-jamie@jamieiles.com>
On Tue, Sep 27, 2011 at 01:16:41PM +0100, Jamie Iles wrote:
> This adds a device tree binding for the VIC based on the of_irq_init()
> support.
>
> Cc: Rob Herring <robherring2@gmail.com>
> Signed-off-by: Jamie Iles <jamie@jamieiles.com>
> ---
> Documentation/devicetree/bindings/arm/vic.txt | 29 ++++++
> arch/arm/common/vic.c | 121 ++++++++++++++++++++-----
> arch/arm/include/asm/hardware/vic.h | 13 +++-
> 3 files changed, 137 insertions(+), 26 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/arm/vic.txt
>
> diff --git a/Documentation/devicetree/bindings/arm/vic.txt b/Documentation/devicetree/bindings/arm/vic.txt
> new file mode 100644
> index 0000000..266716b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/vic.txt
> @@ -0,0 +1,29 @@
> +* ARM Vectored Interrupt Controller
> +
> +One or more Vectored Interrupt Controllers (VIC's) can be connected in an ARM
> +system for interrupt routing. For multiple controllers they can either be
> +nested or have the outputs wire-OR'd together.
> +
> +Required properties:
> +
> +- compatible : should be one of
> + "arm,pl190-vic"
> + "arm,pl192-vic"
> +- interrupt-controller : Identifies the node as an interrupt controller
> +- #interrupt-cells : The number of cells to define the interrupts. Must be 1 as
> + the VIC has no configuration options for interrupt sources. The cell is a u32
> + and defines the interrupt number.
> +- reg : The register bank for the VIC.
> +
> +Optional properties:
> +
> +- interrupts : Interrupt source for parent controllers if the VIC is nested.
> +
> +Example:
> +
> + vic0: interrupt-controller at 60000 {
> + compatible = "arm,pl192-vic";
> + interrupt-controller;
> + #interrupt-cells = <1>;
> + reg = <0x60000 0x1000>;
> + };
> diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
> index 7aa4262..3658579 100644
> --- a/arch/arm/common/vic.c
> +++ b/arch/arm/common/vic.c
> @@ -22,6 +22,10 @@
> #include <linux/init.h>
> #include <linux/list.h>
> #include <linux/io.h>
> +#include <linux/irqdomain.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> #include <linux/syscore_ops.h>
> #include <linux/device.h>
> #include <linux/amba/bus.h>
> @@ -29,7 +33,6 @@
> #include <asm/mach/irq.h>
> #include <asm/hardware/vic.h>
>
> -#ifdef CONFIG_PM
Interesting that this #ifdef is being removed, but no mention of it in
the commit text. It helps with review is some of the implementation
details are described.
> /**
> * struct vic_device - VIC PM device
> * @irq: The IRQ number for the base of the VIC.
> @@ -50,13 +53,15 @@ struct vic_device {
> u32 int_enable;
> u32 soft_int;
> u32 protect;
> +#ifdef CONFIG_IRQ_DOMAIN
> + struct irq_domain domain;
> +#endif /* CONFIG_IRQ_DOMAIN */
> };
>
> /* we cannot allocate memory when VICs are initially registered */
> static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
>
> static int vic_id;
> -#endif /* CONFIG_PM */
>
> /**
> * vic_init2 - common initialisation code
> @@ -156,9 +161,10 @@ static int __init vic_pm_init(void)
> return 0;
> }
> late_initcall(vic_pm_init);
> +#endif /* CONFIG_PM */
>
> /**
> - * vic_pm_register - Register a VIC for later power management control
> + * vic_register - Register a VIC.
Nit: kerneldoc format is:
/**
* function_name() - description
*
> * @base: The base address of the VIC.
> * @irq: The base IRQ for the VIC.
> * @resume_sources: bitmask of interrupts allowed for resume sources.
> @@ -166,24 +172,28 @@ late_initcall(vic_pm_init);
> * Register the VIC with the system device tree so that it can be notified
> * of suspend and resume requests and ensure that the correct actions are
> * taken to re-instate the settings on resume.
> + *
> + * We return the VIC so that it can be used for IRQ domain operations for
> + * device tree translation.
> */
> -static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
> +static struct vic_device * __init
> +vic_register(void __iomem *base, unsigned int irq, u32 resume_sources)
Nit: Linebreaks should be restricted to the argument list. That way
grepping for the function name tells you both what the annotations &
return value is, and that there are more arguments than can be seen
because you don't see closing parentheses.
> {
> struct vic_device *v;
>
> - if (vic_id >= ARRAY_SIZE(vic_devices))
> + if (vic_id >= ARRAY_SIZE(vic_devices)) {
> printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
> - else {
> - v = &vic_devices[vic_id];
> - v->base = base;
> - v->resume_sources = resume_sources;
> - v->irq = irq;
> - vic_id++;
> + return NULL;
> }
> +
> + v = &vic_devices[vic_id];
> + v->base = base;
> + v->resume_sources = resume_sources;
> + v->irq = irq;
> + vic_id++;
> +
> + return v;
> }
> -#else
> -static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
> -#endif /* CONFIG_PM */
>
> static void vic_ack_irq(struct irq_data *d)
> {
> @@ -331,15 +341,9 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
> vic_set_irq_sources(base, irq_start, vic_sources);
> }
>
> -/**
> - * vic_init - initialise a vectored interrupt controller
> - * @base: iomem base address
> - * @irq_start: starting interrupt number, must be muliple of 32
> - * @vic_sources: bitmask of interrupt sources to allow
> - * @resume_sources: bitmask of interrupt sources to allow for resume
> - */
> -void __init vic_init(void __iomem *base, unsigned int irq_start,
> - u32 vic_sources, u32 resume_sources)
> +static struct vic_device * __init
> +__vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,
Ditto here.
> + u32 resume_sources)
> {
> unsigned int i;
> u32 cellid = 0;
> @@ -357,7 +361,7 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
> switch(vendor) {
> case AMBA_VENDOR_ST:
> vic_init_st(base, irq_start, vic_sources);
> - return;
> + return NULL;
> default:
> printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
> /* fall through */
> @@ -375,5 +379,72 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
>
> vic_set_irq_sources(base, irq_start, vic_sources);
>
> - vic_pm_register(base, irq_start, resume_sources);
> + return vic_register(base, irq_start, resume_sources);
> }
> +
> +/**
> + * vic_init - initialise a vectored interrupt controller
> + * @base: iomem base address
> + * @irq_start: starting interrupt number, must be muliple of 32
> + * @vic_sources: bitmask of interrupt sources to allow
> + * @resume_sources: bitmask of interrupt sources to allow for resume
> + */
> +void __init vic_init(void __iomem *base, unsigned int irq_start,
> + u32 vic_sources, u32 resume_sources)
> +{
> + __vic_init(base, irq_start, vic_sources, resume_sources);
> +}
> +
> +#ifdef CONFIG_OF
> +static int
> +vic_irq_domain_dt_translate(struct irq_domain *d, struct device_node *np,
> + const u32 *intspec, unsigned int intsize,
> + unsigned long *out_hwirq, unsigned int *out_type)
> +{
> + if (d->of_node != np)
> + return -EINVAL;
> + if (intsize < 1)
> + return -EINVAL;
> +
> + *out_hwirq = intspec[0];
> + *out_type = IRQ_TYPE_NONE;
> +
> + return 0;
> +}
It matches the simple binding. Just use
irq_domain_simple_dt_translate() directly.
> +
> +static const struct irq_domain_ops vic_irq_domain_ops = {
> + .dt_translate = vic_irq_domain_dt_translate,
> +};
> +
> +int __init vic_of_init(struct device_node *node, struct device_node *parent)
> +{
> + void __iomem *regs = of_iomap(node, 0);
> + struct vic_device *vic;
> + int irq_base;
> +
> + if (WARN_ON(!regs))
> + return -EIO;
> +
> + irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
> + if (WARN_ON(irq_base < 0))
> + goto out_unmap;
> +
> + vic = __vic_init(regs, irq_base, ~0, ~0);
> + if (WARN_ON(!vic))
> + goto out_unmap;
> +
> + vic->domain.irq_base = irq_base;
> + vic->domain.nr_irq = 32;
> + vic->domain.of_node = of_node_get(node);
> + vic->domain.ops = &vic_irq_domain_ops;
> + irq_domain_add(&vic->domain);
> +
> + return 0;
> +
> +out_unmap:
Nit: putting a single space before the label makes 'diff' behave
better.
> + iounmap(regs);
> +
> + return -EIO;
> +}
> +
> +#endif /* CONFIG OF */
> diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
> index 5d72550..df1d895 100644
> --- a/arch/arm/include/asm/hardware/vic.h
> +++ b/arch/arm/include/asm/hardware/vic.h
> @@ -41,7 +41,18 @@
> #define VIC_PL192_VECT_ADDR 0xF00
>
> #ifndef __ASSEMBLY__
> +struct device_node;
> void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
> -#endif
> +
> +#ifdef CONFIG_OF
> +int vic_of_init(struct device_node *node, struct device_node *parent);
> +#else /* CONFIG_OF */
> +static inline int vic_of_init(struct device_node *node,
> + struct device_node *parent)
> +{
> + return -ENOSYS;
> +}
> +#endif /* CONFIG_OF */
Will this ever be referenced when !CONFIG_OF? It shouldn't be.
Otherwise looks good.
g.
^ permalink raw reply
* [PATCH 2/2] ARM: vic: MULTI_IRQ_HANDLER handler
From: Grant Likely @ 2011-09-27 21:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317125802-14386-2-git-send-email-jamie@jamieiles.com>
On Tue, Sep 27, 2011 at 01:16:42PM +0100, Jamie Iles wrote:
> Add a handler for the VIC that is suitable for MULTI_IRQ_HANDLER
> platforms. This only works for platforms with CONFIG_OF=y as we can
> determine which controllers are the primary controllers (no parent).
>
> Signed-off-by: Jamie Iles <jamie@jamieiles.com>
> ---
> arch/arm/common/vic.c | 48 +++++++++++++++++++++++++++++++++++
> arch/arm/include/asm/hardware/vic.h | 1 +
> 2 files changed, 49 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
> index 3658579..e9b72d3 100644
> --- a/arch/arm/common/vic.c
> +++ b/arch/arm/common/vic.c
> @@ -63,6 +63,22 @@ static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
>
> static int vic_id;
>
> +#if defined(CONFIG_OF) && defined(CONFIG_MULTI_IRQ_HANDLER)
> +/*
> + * The root VIC's. We keep track of these so that we can do the IRQ demuxing
> + * as we can have more than one root VIC.
> + */
> +static struct vic_device *vic_root_devices[CONFIG_ARM_VIC_NR];
> +static int nr_root_vics;
> +
> +static void vic_register_root_controller(struct vic_device *vic)
> +{
> + vic_root_devices[nr_root_vics++] = vic;
> +}
> +#else /* CONFIG_OF && CONFIG_MULTI_IRQ_HANDLER */
> +static inline void vic_register_root_controller(struct vic_device *vic) {}
> +#endif /* CONFIG_OF && CONFIG_MULTI_IRQ_HANDLER */
> +
> /**
> * vic_init2 - common initialisation code
> * @base: Base of the VIC.
> @@ -439,6 +455,9 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
> vic->domain.ops = &vic_irq_domain_ops;
> irq_domain_add(&vic->domain);
>
> + if (!parent)
> + vic_register_root_controller(vic);
> +
> return 0;
>
> out_unmap:
> @@ -447,4 +466,33 @@ out_unmap:
> return -EIO;
> }
>
> +#ifdef CONFIG_MULTI_IRQ_HANDLER
> +static void vic_single_handle_irq(struct vic_device *vic, struct pt_regs *regs)
> +{
> + u32 stat, irq;
> + bool handled = false;
> +
> + while (!handled) {
> + stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
> + if (!stat)
> + break;
> +
> + while (stat) {
> + irq = fls(stat) - 1;
> + handle_IRQ(irq + vic->irq, regs);
This is the other reason for irq_domain. Should use
irq_domain_to_irq() here instead of irq + vic->irq. (similar to that,
this driver can also be converted to use (struct irq_data*)->hwirq
instead of the ((struct irq_data*)->irq & 32) that it currently uses.
hwirq was added when irq_domains were added.
> + stat &= ~(1 << irq);
> + handled = true;
> + }
> + }
> +}
> +
> +asmlinkage void __exception_irq_entry vic_handle_irq(struct pt_regs *regs)
> +{
> + int i;
> +
> + for (i = 0; i < nr_root_vics; ++i)
> + vic_single_handle_irq(vic_root_devices[i], regs);
> +}
> +#endif /* CONFIG_MULTI_IRQ_HANDLER */
> +
> #endif /* CONFIG OF */
> diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
> index df1d895..451788c 100644
> --- a/arch/arm/include/asm/hardware/vic.h
> +++ b/arch/arm/include/asm/hardware/vic.h
> @@ -53,6 +53,7 @@ static inline int vic_of_init(struct device_node *node,
> return -ENOSYS;
> }
> #endif /* CONFIG_OF */
> +void vic_handle_irq(struct pt_regs *regs);
> #endif /* __ASSEMBLY__ */
>
> #endif
> --
> 1.7.4.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [RFC PATCH v3] drivercore: Add driver probe deferral mechanism
From: Grant Likely @ 2011-09-27 21:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201109271550.36427.arnd@arndb.de>
On Tue, Sep 27, 2011 at 03:50:36PM +0200, Arnd Bergmann wrote:
> On Monday 26 September 2011, Grant Likely wrote:
> > Actually, in the next iteration, I'm thinking it would be a good idea
> > to create a new #define to only be used by probe deferral. I want it
> > to be easy to find all the drivers that are using this mechanism
> > without needing to filter all the unrelated hits. However, this is a
> > kernel-only thing so it is probably not appropriate to add it to
> > include/asm-generic/errno.h. I could use some guidance/advice as to
> > the best way to handle this.
>
> include/linux/errno.h already has a bunch of kernel-internal error
> codes that are never supposed to be seen in user space. Just
> add one there, the next free one right now is 517, after
> ERESTART_RESTARTBLOCK.
Okay, will do. How does EPROBE_DEFER 518 sound?
g.
^ permalink raw reply
* [PATCH v4] of/irq: introduce of_irq_init
From: Grant Likely @ 2011-09-27 21:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4E81C9B7.9000004@gmail.com>
On Tue, Sep 27, 2011 at 7:03 AM, Rob Herring <robherring2@gmail.com> wrote:
> Grant,
>
> On 09/26/2011 08:53 PM, Grant Likely wrote:
>> On Mon, Sep 26, 2011 at 02:24:43PM -0500, Rob Herring wrote:
>>> From: Rob Herring <rob.herring@calxeda.com>
>>>
>>> of_irq_init will scan the devicetree for matching interrupt controller
>>> nodes. Then it calls an initialization function for each found controller
>>> in the proper order with parent nodes initialized before child nodes.
>>>
>>> Based on initial pseudo code from Grant Likely.
>>>
>>> Changes in v4:
>>> - Drop unnecessary empty list check
>>> - Be more verbose on errors
>>> - Simplify "if (!desc) WARN_ON(1)" to "if (WARN_ON(!desc))"
>>>
>>> Changes in v3:
>>> - add missing kfree's found by Jamie
>>> - Implement Grant's comments to simplify the init loop
>>> - fix function comments
>>>
>>> Changes in v2:
>>> - Complete re-write of list searching code from Grant Likely
>>>
>>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>>> Cc: Grant Likely <grant.likely@secretlab.ca>
>>
>> Looks good to me. ?Merged.
>>
>
> I'm dependent on this and things in rmk's tree for initial highbank
> support, so should this series go in thru arm-soc tree? Several others
> are dependent on this as well.
Sure, it can go in via arm-soc. I don't have anything depending on it
in mine. Add my acked-by.
g.
^ permalink raw reply
* [PATCH v3 0/6] OMAP: omap_device cleanup before device-tree integration
From: Kevin Hilman @ 2011-09-27 21:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1317143886-13285-1-git-send-email-b-cousson@ti.com>
Benoit Cousson <b-cousson@ti.com> writes:
> Hi Kevin,
>
> Here are a couple of cleanups on top of your for_3.2/omap_device branch.
>
> patches are available here:
> git://gitorious.org/omap-pm/linux.git for_3.2/1_omap_device_cleanup
Thanks, this series looks good now. Queuing for v3.2 here:
git://github.com/khilman/linux-omap-pm.git for_3.2/omap_device-2
Kevin
^ 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