From ee1a08f963c5abb5ec2d8c5defffecee7c3f84c8 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Thu, 24 Apr 2008 08:32:26 +1000 Subject: [POWERPC] mpic_pasemi_msi: Failed allocation unnoticed bitmap_find_free_region(), called by mpic_msi_alloc_hwirqs() may return signed, but hwirq is unsigned. A failed allocation remains unnoticed. Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/mpic_pasemi_msi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c index 33cbfb22ce3e..68aff6076675 100644 --- a/arch/powerpc/sysdev/mpic_pasemi_msi.c +++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c @@ -95,6 +95,7 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) unsigned int virq; struct msi_desc *entry; struct msi_msg msg; + int ret; pr_debug("pasemi_msi_setup_msi_irqs, pdev %p nvec %d type %d\n", pdev, nvec, type); @@ -108,8 +109,9 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) * few MSIs for someone, but restrictions will apply to how the * sources can be changed independently. */ - hwirq = mpic_msi_alloc_hwirqs(msi_mpic, ALLOC_CHUNK); - if (hwirq < 0) { + ret = mpic_msi_alloc_hwirqs(msi_mpic, ALLOC_CHUNK); + hwirq = ret; + if (ret < 0) { pr_debug("pasemi_msi: failed allocating hwirq\n"); return hwirq; } -- cgit v1.2.3 From 9d5f525b86453da921360727112161254accc8c1 Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Thu, 24 Apr 2008 09:03:02 +1000 Subject: [POWERPC] mpic_u3msi: Failed allocation unnoticed bitmap_find_free_region(), called by mpic_msi_alloc_hwirqs() may return signed, but hwirq is unsigned. A failed allocation remains unnoticed. Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/mpic_u3msi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c index 1d5a40899b74..6e2f8686fdfc 100644 --- a/arch/powerpc/sysdev/mpic_u3msi.c +++ b/arch/powerpc/sysdev/mpic_u3msi.c @@ -115,17 +115,19 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) struct msi_desc *entry; struct msi_msg msg; u64 addr; + int ret; addr = find_ht_magic_addr(pdev); msg.address_lo = addr & 0xFFFFFFFF; msg.address_hi = addr >> 32; list_for_each_entry(entry, &pdev->msi_list, list) { - hwirq = mpic_msi_alloc_hwirqs(msi_mpic, 1); - if (hwirq < 0) { + ret = mpic_msi_alloc_hwirqs(msi_mpic, 1); + if (ret < 0) { pr_debug("u3msi: failed allocating hwirq\n"); - return hwirq; + return ret; } + hwirq = ret; virq = irq_create_mapping(msi_mpic->irqhost, hwirq); if (virq == NO_IRQ) { -- cgit v1.2.3 From 683307da07afd3a7ee55269ee8cb70c8053b0923 Mon Sep 17 00:00:00 2001 From: Remi Machet Date: Thu, 1 May 2008 10:40:44 +1000 Subject: [POWERPC] Create of_buses for MV64x60 devices For each mv64360 entry in the OpenFirmware database, add the registration of an of_bus to take care of devices connected to the MV64x60 asynchronous devices controller. This change makes it possible for those devices to be detected by drivers that support the of_platform without having a custom call for each of them in the board file. Signed-off-by: Remi Machet Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/mv64x60_dev.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index a132e0de8ca5..32e0ad0ebea8 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -25,6 +26,11 @@ * PowerPC of_platform_bus_type. They support platform_bus_type instead. */ +static struct of_device_id __initdata of_mv64x60_devices[] = { + { .compatible = "marvell,mv64306-devctrl", }, + {} +}; + /* * Create MPSC platform devices */ @@ -484,6 +490,10 @@ static int __init mv64x60_device_setup(void) of_node_put(np); } + /* Now add every node that is on the device bus */ + for_each_compatible_node(np, NULL, "marvell,mv64360") + of_platform_bus_probe(np, of_mv64x60_devices, NULL); + return 0; } arch_initcall(mv64x60_device_setup); -- cgit v1.2.3 From 8fa29d22dcb2aec97f1a508cd3741c6e0b4a9434 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 8 May 2008 14:27:11 +1000 Subject: [POWERPC] sysdev/mpic_msi.c should include sysdev/mpic.h Some of the routines defined in mpic_msi.c are declared mpic.h, so the former should include the latter. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/mpic_msi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c index d272a52ecd24..de3e5e8bc324 100644 --- a/arch/powerpc/sysdev/mpic_msi.c +++ b/arch/powerpc/sysdev/mpic_msi.c @@ -16,6 +16,7 @@ #include #include +#include static void __mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq) { -- cgit v1.2.3 From 0b2cca804ee40495bc92449c3e22f3c3a3f2977a Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 29 Apr 2008 01:38:13 +1000 Subject: [POWERPC] Add 6xx-style HID0_SLEEP support. This adds a function to put a 6xx/7xx/7xxx/83xx family CPU into sleep mode, and return after an interrupt has occurred. It expects to be called with interrupts disabled, and returns with interrupts disabled. Interrupts are enabled while the processor is asleep, but the interrupt that wakes the processor is not handled; it is still pending when this function returns. Signed-off-by: Scott Wood Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/6xx-suspend.S | 52 +++++++++++++++++++++++++++++++++++++++ arch/powerpc/sysdev/Makefile | 4 +++ include/asm-powerpc/mpc6xx.h | 6 +++++ 3 files changed, 62 insertions(+) create mode 100644 arch/powerpc/sysdev/6xx-suspend.S create mode 100644 include/asm-powerpc/mpc6xx.h (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/6xx-suspend.S b/arch/powerpc/sysdev/6xx-suspend.S new file mode 100644 index 000000000000..21cda085d926 --- /dev/null +++ b/arch/powerpc/sysdev/6xx-suspend.S @@ -0,0 +1,52 @@ +/* + * Enter and leave sleep state on chips with 6xx-style HID0 + * power management bits, which don't leave sleep state via reset. + * + * Author: Scott Wood + * + * Copyright (c) 2006-2007 Freescale Semiconductor, Inc. + * + * 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 +#include +#include +#include + +_GLOBAL(mpc6xx_enter_standby) + mflr r4 + + mfspr r5, SPRN_HID0 + rlwinm r5, r5, 0, ~(HID0_DOZE | HID0_NAP) + oris r5, r5, HID0_SLEEP@h + mtspr SPRN_HID0, r5 + isync + + lis r5, ret_from_standby@h + ori r5, r5, ret_from_standby@l + mtlr r5 + + rlwinm r5, r1, 0, 0, 31-THREAD_SHIFT + lwz r6, TI_LOCAL_FLAGS(r5) + ori r6, r6, _TLF_SLEEPING + stw r6, TI_LOCAL_FLAGS(r5) + + mfmsr r5 + ori r5, r5, MSR_EE + oris r5, r5, MSR_POW@h + sync + mtmsr r5 + isync + +1: b 1b + +ret_from_standby: + mfspr r5, SPRN_HID0 + rlwinm r5, r5, 0, ~HID0_SLEEP + mtspr SPRN_HID0, r5 + + mtlr r4 + blr diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 6d386d0071a0..2cc50520a698 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -44,3 +44,7 @@ obj-$(CONFIG_PPC_DCR) += dcr.o obj-$(CONFIG_8xx) += mpc8xx_pic.o cpm1.o obj-$(CONFIG_UCODE_PATCH) += micropatch.o endif + +ifeq ($(CONFIG_SUSPEND),y) +obj-$(CONFIG_6xx) += 6xx-suspend.o +endif diff --git a/include/asm-powerpc/mpc6xx.h b/include/asm-powerpc/mpc6xx.h new file mode 100644 index 000000000000..effc2291beb2 --- /dev/null +++ b/include/asm-powerpc/mpc6xx.h @@ -0,0 +1,6 @@ +#ifndef __ASM_POWERPC_MPC6xx_H +#define __ASM_POWERPC_MPC6xx_H + +void mpc6xx_enter_standby(void); + +#endif -- cgit v1.2.3 From 475ca391b490a683d66bf19999a8a7a24913f139 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 22 May 2008 06:59:23 +1000 Subject: [POWERPC] mpic: Deal with bogus NIRQ in Feature Reporting Register Some chips (like the SoCs from Freescale) report the wrong value in NIRQ and this causes issues if its doesn't match or exceed the value of irq_count. Add a flag that board code can set to just use irq_count instead of FRR[NIRQ]. Eventually we'll add a device tree property with the number of sources. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/mpic.c | 9 ++++++--- include/asm-powerpc/mpic.h | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 8619f2a3f1f6..466e2183e86c 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1144,9 +1144,12 @@ struct mpic * __init mpic_alloc(struct device_node *node, mpic->num_cpus = ((greg_feature & MPIC_GREG_FEATURE_LAST_CPU_MASK) >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1; if (isu_size == 0) - mpic->num_sources = - ((greg_feature & MPIC_GREG_FEATURE_LAST_SRC_MASK) - >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; + if (flags & MPIC_BROKEN_FRR_NIRQS) + mpic->num_sources = mpic->irq_count; + else + mpic->num_sources = + ((greg_feature & MPIC_GREG_FEATURE_LAST_SRC_MASK) + >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; /* Map the per-CPU registers */ for (i = 0; i < mpic->num_cpus; i++) { diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h index 943c5a3fac8a..6802570f4240 100644 --- a/include/asm-powerpc/mpic.h +++ b/include/asm-powerpc/mpic.h @@ -353,6 +353,8 @@ struct mpic #define MPIC_ENABLE_MCK 0x00000200 /* Disable bias among target selection, spread interrupts evenly */ #define MPIC_NO_BIAS 0x00000400 +/* Ignore NIRQS as reported by FRR */ +#define MPIC_BROKEN_FRR_NIRQS 0x00000800 /* MPIC HW modification ID */ #define MPIC_REGSET_MASK 0xf0000000 -- cgit v1.2.3 From b786af117b360843349cf66165c4efa0217ca2a7 Mon Sep 17 00:00:00 2001 From: Stephen Neuendorffer Date: Wed, 7 May 2008 04:29:17 +1000 Subject: [POWERPC] Refactor DCR code Previously, DCR support was configured at compile time to either use MMIO or native dcr instructions. Although this works for most platforms, it fails on FPGA platforms: 1) Systems may include more than one DCR bus. 2) Systems may be native DCR capable and still use memory mapped DCR interface. This patch provides runtime support based on the device trees for the case where CONFIG_PPC_DCR_MMIO and CONFIG_PPC_DCR_NATIVE are both selected. Previously, this was a poorly defined configuration, which happened to provide NATIVE support. The runtime selection is made based on the dcr-controller having a 'dcr-access-method' attribute in the device tree. If only one of the above options is selected, then the code uses #defines to select only the used code in order to avoid introducing overhead in existing usage. Signed-off-by: Stephen Neuendorffer Signed-off-by: Josh Boyer --- arch/powerpc/sysdev/dcr.c | 154 ++++++++++++++++++++++++++++++-------- include/asm-powerpc/dcr-generic.h | 49 ++++++++++++ include/asm-powerpc/dcr-mmio.h | 20 +++-- include/asm-powerpc/dcr-native.h | 16 ++-- include/asm-powerpc/dcr.h | 39 +++++++++- 5 files changed, 231 insertions(+), 47 deletions(-) create mode 100644 include/asm-powerpc/dcr-generic.h (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c index 437e48d3ae33..5f39a79b0660 100644 --- a/arch/powerpc/sysdev/dcr.c +++ b/arch/powerpc/sysdev/dcr.c @@ -23,6 +23,105 @@ #include #include +static struct device_node *find_dcr_parent(struct device_node *node) +{ + struct device_node *par, *tmp; + const u32 *p; + + for (par = of_node_get(node); par;) { + if (of_get_property(par, "dcr-controller", NULL)) + break; + p = of_get_property(par, "dcr-parent", NULL); + tmp = par; + if (p == NULL) + par = of_get_parent(par); + else + par = of_find_node_by_phandle(*p); + of_node_put(tmp); + } + return par; +} + +#if defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO) + +bool dcr_map_ok_generic(dcr_host_t host) +{ + if (host.type == DCR_HOST_NATIVE) + return dcr_map_ok_native(host.host.native); + else if (host.type == DCR_HOST_MMIO) + return dcr_map_ok_mmio(host.host.mmio); + else + return 0; +} +EXPORT_SYMBOL_GPL(dcr_map_ok_generic); + +dcr_host_t dcr_map_generic(struct device_node *dev, + unsigned int dcr_n, + unsigned int dcr_c) +{ + dcr_host_t host; + struct device_node *dp; + const char *prop; + + host.type = DCR_HOST_INVALID; + + dp = find_dcr_parent(dev); + if (dp == NULL) + return host; + + prop = of_get_property(dp, "dcr-access-method", NULL); + + pr_debug("dcr_map_generic(dcr-access-method = %s)\n", prop); + + if (!strcmp(prop, "native")) { + host.type = DCR_HOST_NATIVE; + host.host.native = dcr_map_native(dev, dcr_n, dcr_c); + } else if (!strcmp(prop, "mmio")) { + host.type = DCR_HOST_MMIO; + host.host.mmio = dcr_map_mmio(dev, dcr_n, dcr_c); + } + + of_node_put(dp); + return host; +} +EXPORT_SYMBOL_GPL(dcr_map_generic); + +void dcr_unmap_generic(dcr_host_t host, unsigned int dcr_c) +{ + if (host.type == DCR_HOST_NATIVE) + dcr_unmap_native(host.host.native, dcr_c); + else if (host.type == DCR_HOST_MMIO) + dcr_unmap_mmio(host.host.mmio, dcr_c); + else /* host.type == DCR_HOST_INVALID */ + WARN_ON(true); +} +EXPORT_SYMBOL_GPL(dcr_unmap_generic); + +u32 dcr_read_generic(dcr_host_t host, unsigned int dcr_n) +{ + if (host.type == DCR_HOST_NATIVE) + return dcr_read_native(host.host.native, dcr_n); + else if (host.type == DCR_HOST_MMIO) + return dcr_read_mmio(host.host.mmio, dcr_n); + else /* host.type == DCR_HOST_INVALID */ + WARN_ON(true); + return 0; +} +EXPORT_SYMBOL_GPL(dcr_read_generic); + +void dcr_write_generic(dcr_host_t host, unsigned int dcr_n, u32 value) +{ + if (host.type == DCR_HOST_NATIVE) + dcr_write_native(host.host.native, dcr_n, value); + else if (host.type == DCR_HOST_MMIO) + dcr_write_mmio(host.host.mmio, dcr_n, value); + else /* host.type == DCR_HOST_INVALID */ + WARN_ON(true); +} +EXPORT_SYMBOL_GPL(dcr_write_generic); + +#endif /* defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO) */ + unsigned int dcr_resource_start(struct device_node *np, unsigned int index) { unsigned int ds; @@ -47,26 +146,7 @@ unsigned int dcr_resource_len(struct device_node *np, unsigned int index) } EXPORT_SYMBOL_GPL(dcr_resource_len); -#ifndef CONFIG_PPC_DCR_NATIVE - -static struct device_node * find_dcr_parent(struct device_node * node) -{ - struct device_node *par, *tmp; - const u32 *p; - - for (par = of_node_get(node); par;) { - if (of_get_property(par, "dcr-controller", NULL)) - break; - p = of_get_property(par, "dcr-parent", NULL); - tmp = par; - if (p == NULL) - par = of_get_parent(par); - else - par = of_find_node_by_phandle(*p); - of_node_put(tmp); - } - return par; -} +#ifdef CONFIG_PPC_DCR_MMIO u64 of_translate_dcr_address(struct device_node *dev, unsigned int dcr_n, @@ -75,7 +155,7 @@ u64 of_translate_dcr_address(struct device_node *dev, struct device_node *dp; const u32 *p; unsigned int stride; - u64 ret; + u64 ret = OF_BAD_ADDR; dp = find_dcr_parent(dev); if (dp == NULL) @@ -90,7 +170,7 @@ u64 of_translate_dcr_address(struct device_node *dev, if (p == NULL) p = of_get_property(dp, "dcr-mmio-space", NULL); if (p == NULL) - return OF_BAD_ADDR; + goto done; /* Maybe could do some better range checking here */ ret = of_translate_address(dp, p); @@ -98,21 +178,25 @@ u64 of_translate_dcr_address(struct device_node *dev, ret += (u64)(stride) * (u64)dcr_n; if (out_stride) *out_stride = stride; + + done: + of_node_put(dp); return ret; } -dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n, - unsigned int dcr_c) +dcr_host_mmio_t dcr_map_mmio(struct device_node *dev, + unsigned int dcr_n, + unsigned int dcr_c) { - dcr_host_t ret = { .token = NULL, .stride = 0, .base = dcr_n }; + dcr_host_mmio_t ret = { .token = NULL, .stride = 0, .base = dcr_n }; u64 addr; pr_debug("dcr_map(%s, 0x%x, 0x%x)\n", dev->full_name, dcr_n, dcr_c); addr = of_translate_dcr_address(dev, dcr_n, &ret.stride); - pr_debug("translates to addr: 0x%lx, stride: 0x%x\n", - addr, ret.stride); + pr_debug("translates to addr: 0x%llx, stride: 0x%x\n", + (unsigned long long) addr, ret.stride); if (addr == OF_BAD_ADDR) return ret; pr_debug("mapping 0x%x bytes\n", dcr_c * ret.stride); @@ -124,11 +208,11 @@ dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n, ret.token -= dcr_n * ret.stride; return ret; } -EXPORT_SYMBOL_GPL(dcr_map); +EXPORT_SYMBOL_GPL(dcr_map_mmio); -void dcr_unmap(dcr_host_t host, unsigned int dcr_c) +void dcr_unmap_mmio(dcr_host_mmio_t host, unsigned int dcr_c) { - dcr_host_t h = host; + dcr_host_mmio_t h = host; if (h.token == NULL) return; @@ -136,7 +220,11 @@ void dcr_unmap(dcr_host_t host, unsigned int dcr_c) iounmap(h.token); h.token = NULL; } -EXPORT_SYMBOL_GPL(dcr_unmap); -#else /* defined(CONFIG_PPC_DCR_NATIVE) */ +EXPORT_SYMBOL_GPL(dcr_unmap_mmio); + +#endif /* defined(CONFIG_PPC_DCR_MMIO) */ + +#ifdef CONFIG_PPC_DCR_NATIVE DEFINE_SPINLOCK(dcr_ind_lock); -#endif /* !defined(CONFIG_PPC_DCR_NATIVE) */ +#endif /* defined(CONFIG_PPC_DCR_NATIVE) */ + diff --git a/include/asm-powerpc/dcr-generic.h b/include/asm-powerpc/dcr-generic.h new file mode 100644 index 000000000000..35b71599ec46 --- /dev/null +++ b/include/asm-powerpc/dcr-generic.h @@ -0,0 +1,49 @@ +/* + * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp. + * + * + * 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 + */ + +#ifndef _ASM_POWERPC_DCR_GENERIC_H +#define _ASM_POWERPC_DCR_GENERIC_H +#ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + +enum host_type_t {DCR_HOST_MMIO, DCR_HOST_NATIVE, DCR_HOST_INVALID}; + +typedef struct { + enum host_type_t type; + union { + dcr_host_mmio_t mmio; + dcr_host_native_t native; + } host; +} dcr_host_t; + +extern bool dcr_map_ok_generic(dcr_host_t host); + +extern dcr_host_t dcr_map_generic(struct device_node *dev, unsigned int dcr_n, + unsigned int dcr_c); +extern void dcr_unmap_generic(dcr_host_t host, unsigned int dcr_c); + +extern u32 dcr_read_generic(dcr_host_t host, unsigned int dcr_n); + +extern void dcr_write_generic(dcr_host_t host, unsigned int dcr_n, u32 value); + +#endif /* __ASSEMBLY__ */ +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_DCR_GENERIC_H */ + + diff --git a/include/asm-powerpc/dcr-mmio.h b/include/asm-powerpc/dcr-mmio.h index 08532ff1899c..acd491dbd45a 100644 --- a/include/asm-powerpc/dcr-mmio.h +++ b/include/asm-powerpc/dcr-mmio.h @@ -27,20 +27,26 @@ typedef struct { void __iomem *token; unsigned int stride; unsigned int base; -} dcr_host_t; +} dcr_host_mmio_t; -#define DCR_MAP_OK(host) ((host).token != NULL) +static inline bool dcr_map_ok_mmio(dcr_host_mmio_t host) +{ + return host.token != NULL; +} -extern dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n, - unsigned int dcr_c); -extern void dcr_unmap(dcr_host_t host, unsigned int dcr_c); +extern dcr_host_mmio_t dcr_map_mmio(struct device_node *dev, + unsigned int dcr_n, + unsigned int dcr_c); +extern void dcr_unmap_mmio(dcr_host_mmio_t host, unsigned int dcr_c); -static inline u32 dcr_read(dcr_host_t host, unsigned int dcr_n) +static inline u32 dcr_read_mmio(dcr_host_mmio_t host, unsigned int dcr_n) { return in_be32(host.token + ((host.base + dcr_n) * host.stride)); } -static inline void dcr_write(dcr_host_t host, unsigned int dcr_n, u32 value) +static inline void dcr_write_mmio(dcr_host_mmio_t host, + unsigned int dcr_n, + u32 value) { out_be32(host.token + ((host.base + dcr_n) * host.stride), value); } diff --git a/include/asm-powerpc/dcr-native.h b/include/asm-powerpc/dcr-native.h index f8398ce80372..72d2b72c7390 100644 --- a/include/asm-powerpc/dcr-native.h +++ b/include/asm-powerpc/dcr-native.h @@ -26,14 +26,18 @@ typedef struct { unsigned int base; -} dcr_host_t; +} dcr_host_native_t; -#define DCR_MAP_OK(host) (1) +static inline bool dcr_map_ok_native(dcr_host_native_t host) +{ + return 1; +} -#define dcr_map(dev, dcr_n, dcr_c) ((dcr_host_t){ .base = (dcr_n) }) -#define dcr_unmap(host, dcr_c) do {} while (0) -#define dcr_read(host, dcr_n) mfdcr(dcr_n + host.base) -#define dcr_write(host, dcr_n, value) mtdcr(dcr_n + host.base, value) +#define dcr_map_native(dev, dcr_n, dcr_c) \ + ((dcr_host_native_t){ .base = (dcr_n) }) +#define dcr_unmap_native(host, dcr_c) do {} while (0) +#define dcr_read_native(host, dcr_n) mfdcr(dcr_n + host.base) +#define dcr_write_native(host, dcr_n, value) mtdcr(dcr_n + host.base, value) /* Device Control Registers */ void __mtdcr(int reg, unsigned int val); diff --git a/include/asm-powerpc/dcr.h b/include/asm-powerpc/dcr.h index 9338d50538f1..53b283050ab3 100644 --- a/include/asm-powerpc/dcr.h +++ b/include/asm-powerpc/dcr.h @@ -20,14 +20,50 @@ #ifndef _ASM_POWERPC_DCR_H #define _ASM_POWERPC_DCR_H #ifdef __KERNEL__ +#ifndef __ASSEMBLY__ #ifdef CONFIG_PPC_DCR #ifdef CONFIG_PPC_DCR_NATIVE #include -#else +#endif + +#ifdef CONFIG_PPC_DCR_MMIO #include #endif + +/* Indirection layer for providing both NATIVE and MMIO support. */ + +#if defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO) + +#include + +#define DCR_MAP_OK(host) dcr_map_ok_generic(host) +#define dcr_map(dev, dcr_n, dcr_c) dcr_map_generic(dev, dcr_n, dcr_c) +#define dcr_unmap(host, dcr_c) dcr_unmap_generic(host, dcr_c) +#define dcr_read(host, dcr_n) dcr_read_generic(host, dcr_n) +#define dcr_write(host, dcr_n, value) dcr_write_generic(host, dcr_n, value) + +#else + +#ifdef CONFIG_PPC_DCR_NATIVE +typedef dcr_host_native_t dcr_host_t; +#define DCR_MAP_OK(host) dcr_map_ok_native(host) +#define dcr_map(dev, dcr_n, dcr_c) dcr_map_native(dev, dcr_n, dcr_c) +#define dcr_unmap(host, dcr_c) dcr_unmap_native(host, dcr_c) +#define dcr_read(host, dcr_n) dcr_read_native(host, dcr_n) +#define dcr_write(host, dcr_n, value) dcr_write_native(host, dcr_n, value) +#else +typedef dcr_host_mmio_t dcr_host_t; +#define DCR_MAP_OK(host) dcr_map_ok_mmio(host) +#define dcr_map(dev, dcr_n, dcr_c) dcr_map_mmio(dev, dcr_n, dcr_c) +#define dcr_unmap(host, dcr_c) dcr_unmap_mmio(host, dcr_c) +#define dcr_read(host, dcr_n) dcr_read_mmio(host, dcr_n) +#define dcr_write(host, dcr_n, value) dcr_write_mmio(host, dcr_n, value) +#endif + +#endif /* defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO) */ + /* * On CONFIG_PPC_MERGE, we have additional helpers to read the DCR * base from the device-tree @@ -41,5 +77,6 @@ extern unsigned int dcr_resource_len(struct device_node *np, #endif /* CONFIG_PPC_MERGE */ #endif /* CONFIG_PPC_DCR */ +#endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_DCR_H */ -- cgit v1.2.3 From 0723abd0b2c9d4603b8c51d6615800c2439a328e Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 20 May 2008 07:59:23 -0500 Subject: [POWERPC] 4xx: Fix compiler warning on DCR_NATIVE only builds With the recent DCR code rework, we get a compiler warning about find_dcr_parent being defined but not used. This fixes it by only defining the function if CONFIG_PPC_DCR_MMIO is set. Signed-off-by: Josh Boyer --- arch/powerpc/sysdev/dcr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c index 5f39a79b0660..a8ba9983dd5a 100644 --- a/arch/powerpc/sysdev/dcr.c +++ b/arch/powerpc/sysdev/dcr.c @@ -23,6 +23,7 @@ #include #include +#ifdef CONFIG_PPC_DCR_MMIO static struct device_node *find_dcr_parent(struct device_node *node) { struct device_node *par, *tmp; @@ -41,6 +42,7 @@ static struct device_node *find_dcr_parent(struct device_node *node) } return par; } +#endif #if defined(CONFIG_PPC_DCR_NATIVE) && defined(CONFIG_PPC_DCR_MMIO) -- cgit v1.2.3 From 34e36c1541fe70e5b3842a3278c0e7631d31f4cb Mon Sep 17 00:00:00 2001 From: Jason Jin Date: Fri, 23 May 2008 16:32:46 +0800 Subject: [POWERPC] fsl: PCIe MSI support for 83xx/85xx/86xx processors. This MSI driver can be used on 83xx/85xx/86xx board. In this driver, virtual interrupt host and chip were setup. There are 256 MSI interrupts in this host, Every 32 MSI interrupts cascaded to one IPIC/MPIC interrupt. The chip was treated as edge sensitive and some necessary functions were setup for this chip. Before using the MSI interrupt, PCI/PCIE device need to ask for a MSI interrupt in the 256 MSI interrupts. A 256bit bitmap show which MSI interrupt was used, reserve bit in the bitmap can be used to force the device use some designate MSI interrupt in the 256 MSI interrupts. Sometimes this is useful for testing the all the MSI interrupts. The msi-available-ranges property in the dts file was used for this purpose. Signed-off-by: Jason Jin Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/Makefile | 3 +- arch/powerpc/sysdev/fsl_msi.c | 436 ++++++++++++++++++++++++++++++++++++++++++ arch/powerpc/sysdev/fsl_msi.h | 42 ++++ arch/powerpc/sysdev/fsl_pci.c | 14 ++ 4 files changed, 494 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/sysdev/fsl_msi.c create mode 100644 arch/powerpc/sysdev/fsl_msi.h (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 2cc50520a698..dd6dff3ffb0f 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -4,6 +4,7 @@ endif mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y) +fsl-msi-obj-$(CONFIG_PCI_MSI) += fsl_msi.o obj-$(CONFIG_PPC_MPC106) += grackle.o obj-$(CONFIG_PPC_DCR_NATIVE) += dcr-low.o @@ -11,7 +12,7 @@ obj-$(CONFIG_PPC_PMI) += pmi.o obj-$(CONFIG_U3_DART) += dart_iommu.o obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o -obj-$(CONFIG_FSL_PCI) += fsl_pci.o +obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) obj-$(CONFIG_FSL_LBC) += fsl_lbc.o obj-$(CONFIG_RAPIDIO) += fsl_rio.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c new file mode 100644 index 000000000000..9d0685babbd5 --- /dev/null +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -0,0 +1,436 @@ +/* + * Copyright (C) 2007-2008 Freescale Semiconductor, Inc. All rights reserved. + * + * Author: Tony Li + * Jason Jin + * + * The hwirq alloc and free code reuse from sysdev/mpic_msi.c + * + * 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; version 2 of the + * License. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fsl_msi.h" + +struct fsl_msi_feature { + u32 fsl_pic_ip; + u32 msiir_offset; +}; + +static struct fsl_msi *fsl_msi; + +static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg) +{ + return in_be32(base + (reg >> 2)); +} + +static inline void fsl_msi_write(u32 __iomem *base, + unsigned int reg, u32 value) +{ + out_be32(base + (reg >> 2), value); +} + +/* + * We do not need this actually. The MSIR register has been read once + * in the cascade interrupt. So, this MSI interrupt has been acked +*/ +static void fsl_msi_end_irq(unsigned int virq) +{ +} + +static struct irq_chip fsl_msi_chip = { + .mask = mask_msi_irq, + .unmask = unmask_msi_irq, + .ack = fsl_msi_end_irq, + .typename = " FSL-MSI ", +}; + +static int fsl_msi_host_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct irq_chip *chip = &fsl_msi_chip; + + get_irq_desc(virq)->status |= IRQ_TYPE_EDGE_FALLING; + + set_irq_chip_and_handler(virq, chip, handle_edge_irq); + + return 0; +} + +static struct irq_host_ops fsl_msi_host_ops = { + .map = fsl_msi_host_map, +}; + +irq_hw_number_t fsl_msi_alloc_hwirqs(struct fsl_msi *msi, int num) +{ + unsigned long flags; + int offset, order = get_count_order(num); + + spin_lock_irqsave(&msi->bitmap_lock, flags); + + offset = bitmap_find_free_region(msi->fsl_msi_bitmap, + NR_MSI_IRQS, order); + + spin_unlock_irqrestore(&msi->bitmap_lock, flags); + + pr_debug("%s: allocated 0x%x (2^%d) at offset 0x%x\n", + __func__, num, order, offset); + + return offset; +} + +void fsl_msi_free_hwirqs(struct fsl_msi *msi, int offset, int num) +{ + unsigned long flags; + int order = get_count_order(num); + + pr_debug("%s: freeing 0x%x (2^%d) at offset 0x%x\n", + __func__, num, order, offset); + + spin_lock_irqsave(&msi->bitmap_lock, flags); + bitmap_release_region(msi->fsl_msi_bitmap, offset, order); + spin_unlock_irqrestore(&msi->bitmap_lock, flags); +} + +static int fsl_msi_free_dt_hwirqs(struct fsl_msi *msi) +{ + int i, len; + const u32 *p; + + bitmap_allocate_region(msi->fsl_msi_bitmap, 0, + get_count_order(NR_MSI_IRQS)); + + p = of_get_property(msi->of_node, "msi-available-ranges", &len); + + if (!p) { + /* No msi-available-ranges property, + * All the 256 MSI interrupts can be used + */ + fsl_msi_free_hwirqs(msi, 0, 0x100); + return 0; + } + + if ((len % (2 * sizeof(u32))) != 0) { + printk(KERN_WARNING "fsl_msi: Malformed msi-available-ranges " + "property on %s\n", msi->of_node->full_name); + return -EINVAL; + } + + /* Format is: ( )+ */ + len /= 2 * sizeof(u32); + for (i = 0; i < len; i++, p += 2) + fsl_msi_free_hwirqs(msi, *p, *(p + 1)); + + return 0; +} + +static int fsl_msi_init_allocator(struct fsl_msi *msi_data) +{ + int rc, size; + + size = BITS_TO_LONGS(NR_MSI_IRQS) * sizeof(u32); + + msi_data->fsl_msi_bitmap = kzalloc(size, GFP_KERNEL); + + if (msi_data->fsl_msi_bitmap == NULL) { + pr_debug("%s: ENOMEM allocating allocator bitmap!\n", + __func__); + return -ENOMEM; + } + + rc = fsl_msi_free_dt_hwirqs(msi_data); + if (rc) + goto out_free; + + return 0; +out_free: + kfree(msi_data->fsl_msi_bitmap); + + msi_data->fsl_msi_bitmap = NULL; + return rc; + +} + +static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type) +{ + if (type == PCI_CAP_ID_MSIX) + pr_debug("fslmsi: MSI-X untested, trying anyway.\n"); + + return 0; +} + +static void fsl_teardown_msi_irqs(struct pci_dev *pdev) +{ + struct msi_desc *entry; + struct fsl_msi *msi_data = fsl_msi; + + list_for_each_entry(entry, &pdev->msi_list, list) { + if (entry->irq == NO_IRQ) + continue; + set_irq_msi(entry->irq, NULL); + fsl_msi_free_hwirqs(msi_data, virq_to_hw(entry->irq), 1); + irq_dispose_mapping(entry->irq); + } + + return; +} + +static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, + struct msi_msg *msg) +{ + struct fsl_msi *msi_data = fsl_msi; + + msg->address_lo = msi_data->msi_addr_lo; + msg->address_hi = msi_data->msi_addr_hi; + msg->data = hwirq; + + pr_debug("%s: allocated srs: %d, ibs: %d\n", + __func__, hwirq / IRQS_PER_MSI_REG, hwirq % IRQS_PER_MSI_REG); +} + +static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) +{ + irq_hw_number_t hwirq; + int rc; + unsigned int virq; + struct msi_desc *entry; + struct msi_msg msg; + struct fsl_msi *msi_data = fsl_msi; + + list_for_each_entry(entry, &pdev->msi_list, list) { + hwirq = fsl_msi_alloc_hwirqs(msi_data, 1); + if (hwirq < 0) { + rc = hwirq; + pr_debug("%s: fail allocating msi interrupt\n", + __func__); + goto out_free; + } + + virq = irq_create_mapping(msi_data->irqhost, hwirq); + + if (virq == NO_IRQ) { + pr_debug("%s: fail mapping hwirq 0x%lx\n", + __func__, hwirq); + fsl_msi_free_hwirqs(msi_data, hwirq, 1); + rc = -ENOSPC; + goto out_free; + } + set_irq_msi(virq, entry); + + fsl_compose_msi_msg(pdev, hwirq, &msg); + write_msi_msg(virq, &msg); + } + return 0; + +out_free: + return rc; +} + +void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) +{ + unsigned int cascade_irq; + struct fsl_msi *msi_data = fsl_msi; + int msir_index = -1; + u32 msir_value = 0; + u32 intr_index; + u32 have_shift = 0; + + spin_lock(&desc->lock); + if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) { + if (desc->chip->mask_ack) + desc->chip->mask_ack(irq); + else { + desc->chip->mask(irq); + desc->chip->ack(irq); + } + } + + if (unlikely(desc->status & IRQ_INPROGRESS)) + goto unlock; + + msir_index = (int)(desc->handler_data); + + if (msir_index >= NR_MSI_REG) + cascade_irq = NO_IRQ; + + desc->status |= IRQ_INPROGRESS; + switch (fsl_msi->feature & FSL_PIC_IP_MASK) { + case FSL_PIC_IP_MPIC: + msir_value = fsl_msi_read(msi_data->msi_regs, + msir_index * 0x10); + break; + case FSL_PIC_IP_IPIC: + msir_value = fsl_msi_read(msi_data->msi_regs, msir_index * 0x4); + break; + } + + while (msir_value) { + intr_index = ffs(msir_value) - 1; + + cascade_irq = irq_linear_revmap(msi_data->irqhost, + (msir_index * IRQS_PER_MSI_REG + + intr_index + have_shift)); + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq); + have_shift += (intr_index + 1); + msir_value = (msir_value >> (intr_index + 1)); + } + desc->status &= ~IRQ_INPROGRESS; + + switch (msi_data->feature & FSL_PIC_IP_MASK) { + case FSL_PIC_IP_MPIC: + desc->chip->eoi(irq); + break; + case FSL_PIC_IP_IPIC: + if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) + desc->chip->unmask(irq); + break; + } +unlock: + spin_unlock(&desc->lock); +} + +static int __devinit fsl_of_msi_probe(struct of_device *dev, + const struct of_device_id *match) +{ + struct fsl_msi *msi; + struct resource res; + int err, i, count; + int rc; + int virt_msir; + const u32 *p; + struct fsl_msi_feature *tmp_data; + + printk(KERN_DEBUG "Setting up Freescale MSI support\n"); + + msi = kzalloc(sizeof(struct fsl_msi), GFP_KERNEL); + if (!msi) { + dev_err(&dev->dev, "No memory for MSI structure\n"); + err = -ENOMEM; + goto error_out; + } + + msi->of_node = of_node_get(dev->node); + + msi->irqhost = irq_alloc_host(of_node_get(dev->node), + IRQ_HOST_MAP_LINEAR, + NR_MSI_IRQS, &fsl_msi_host_ops, 0); + if (msi->irqhost == NULL) { + dev_err(&dev->dev, "No memory for MSI irqhost\n"); + of_node_put(dev->node); + err = -ENOMEM; + goto error_out; + } + + /* Get the MSI reg base */ + err = of_address_to_resource(dev->node, 0, &res); + if (err) { + dev_err(&dev->dev, "%s resource error!\n", + dev->node->full_name); + goto error_out; + } + + msi->msi_regs = ioremap(res.start, res.end - res.start + 1); + if (!msi->msi_regs) { + dev_err(&dev->dev, "ioremap problem failed\n"); + goto error_out; + } + + tmp_data = (struct fsl_msi_feature *)match->data; + + msi->feature = tmp_data->fsl_pic_ip; + + msi->irqhost->host_data = msi; + + msi->msi_addr_hi = 0x0; + msi->msi_addr_lo = res.start + tmp_data->msiir_offset; + + rc = fsl_msi_init_allocator(msi); + if (rc) { + dev_err(&dev->dev, "Error allocating MSI bitmap\n"); + goto error_out; + } + + p = of_get_property(dev->node, "interrupts", &count); + if (!p) { + dev_err(&dev->dev, "no interrupts property found on %s\n", + dev->node->full_name); + err = -ENODEV; + goto error_out; + } + if (count % 8 != 0) { + dev_err(&dev->dev, "Malformed interrupts property on %s\n", + dev->node->full_name); + err = -EINVAL; + goto error_out; + } + + count /= sizeof(u32); + for (i = 0; i < count / 2; i++) { + if (i > NR_MSI_REG) + break; + virt_msir = irq_of_parse_and_map(dev->node, i); + if (virt_msir != NO_IRQ) { + set_irq_data(virt_msir, (void *)i); + set_irq_chained_handler(virt_msir, fsl_msi_cascade); + } + } + + fsl_msi = msi; + + WARN_ON(ppc_md.setup_msi_irqs); + ppc_md.setup_msi_irqs = fsl_setup_msi_irqs; + ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs; + ppc_md.msi_check_device = fsl_msi_check_device; + return 0; +error_out: + kfree(msi); + return err; +} + +static const struct fsl_msi_feature mpic_msi_feature = { + .fsl_pic_ip = FSL_PIC_IP_MPIC, + .msiir_offset = 0x140, +}; + +static const struct fsl_msi_feature ipic_msi_feature = { + .fsl_pic_ip = FSL_PIC_IP_IPIC, + .msiir_offset = 0x38, +}; + +static const struct of_device_id fsl_of_msi_ids[] = { + { + .compatible = "fsl,mpic-msi", + .data = (void *)&mpic_msi_feature, + }, + { + .compatible = "fsl,ipic-msi", + .data = (void *)&ipic_msi_feature, + }, + {} +}; + +static struct of_platform_driver fsl_of_msi_driver = { + .name = "fsl-msi", + .match_table = fsl_of_msi_ids, + .probe = fsl_of_msi_probe, +}; + +static __init int fsl_of_msi_init(void) +{ + return of_register_platform_driver(&fsl_of_msi_driver); +} + +subsys_initcall(fsl_of_msi_init); diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h new file mode 100644 index 000000000000..a653468521fa --- /dev/null +++ b/arch/powerpc/sysdev/fsl_msi.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2007-2008 Freescale Semiconductor, Inc. All rights reserved. + * + * Author: Tony Li + * Jason Jin + * + * 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; version 2 of the + * License. + * + */ +#ifndef _POWERPC_SYSDEV_FSL_MSI_H +#define _POWERPC_SYSDEV_FSL_MSI_H + +#define NR_MSI_REG 8 +#define IRQS_PER_MSI_REG 32 +#define NR_MSI_IRQS (NR_MSI_REG * IRQS_PER_MSI_REG) + +#define FSL_PIC_IP_MASK 0x0000000F +#define FSL_PIC_IP_MPIC 0x00000001 +#define FSL_PIC_IP_IPIC 0x00000002 + +struct fsl_msi { + /* Device node of the MSI interrupt*/ + struct device_node *of_node; + + struct irq_host *irqhost; + + unsigned long cascade_irq; + + u32 msi_addr_lo; + u32 msi_addr_hi; + void __iomem *msi_regs; + u32 feature; + + unsigned long *fsl_msi_bitmap; + spinlock_t bitmap_lock; +}; + +#endif /* _POWERPC_SYSDEV_FSL_MSI_H */ + diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index bf13c2174a4e..52a5f7f41b4a 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -106,6 +106,16 @@ void __init setup_pci_cmd(struct pci_controller *hose) } } +#ifdef CONFIG_PCI_MSI +void __init setup_pci_pcsrbar(struct pci_controller *hose) +{ + phys_addr_t immr_base; + + immr_base = get_immrbase(); + early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, immr_base); +} +#endif + static int fsl_pcie_bus_fixup; static void __init quirk_fsl_pcie_header(struct pci_dev *dev) @@ -211,6 +221,10 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary) /* Setup PEX window registers */ setup_pci_atmu(hose, &rsrc); + /* Setup PEXCSRBAR */ +#ifdef CONFIG_PCI_MSI + setup_pci_pcsrbar(hose); +#endif return 0; } -- cgit v1.2.3 From 692d1037e6914a8a32a7a9fba416684c75c7efca Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 23 May 2008 17:41:02 +0400 Subject: [POWERPC] fsl_msi: few (mostly cosmetic) fixes This patch fixes few cosmetic issues, also removes unused function, makes some functions static and reduces #ifdef count. Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/fsl_msi.c | 43 ++++++++++++++++++------------------------- arch/powerpc/sysdev/fsl_pci.c | 8 +++----- 2 files changed, 21 insertions(+), 30 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 9d0685babbd5..2c5187cc8a24 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -36,12 +36,6 @@ static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg) return in_be32(base + (reg >> 2)); } -static inline void fsl_msi_write(u32 __iomem *base, - unsigned int reg, u32 value) -{ - out_be32(base + (reg >> 2), value); -} - /* * We do not need this actually. The MSIR register has been read once * in the cascade interrupt. So, this MSI interrupt has been acked @@ -64,7 +58,7 @@ static int fsl_msi_host_map(struct irq_host *h, unsigned int virq, get_irq_desc(virq)->status |= IRQ_TYPE_EDGE_FALLING; - set_irq_chip_and_handler(virq, chip, handle_edge_irq); + set_irq_chip_and_handler(virq, chip, handle_edge_irq); return 0; } @@ -73,10 +67,11 @@ static struct irq_host_ops fsl_msi_host_ops = { .map = fsl_msi_host_map, }; -irq_hw_number_t fsl_msi_alloc_hwirqs(struct fsl_msi *msi, int num) +static irq_hw_number_t fsl_msi_alloc_hwirqs(struct fsl_msi *msi, int num) { unsigned long flags; - int offset, order = get_count_order(num); + int order = get_count_order(num); + int offset; spin_lock_irqsave(&msi->bitmap_lock, flags); @@ -91,7 +86,7 @@ irq_hw_number_t fsl_msi_alloc_hwirqs(struct fsl_msi *msi, int num) return offset; } -void fsl_msi_free_hwirqs(struct fsl_msi *msi, int offset, int num) +static void fsl_msi_free_hwirqs(struct fsl_msi *msi, int offset, int num) { unsigned long flags; int order = get_count_order(num); @@ -106,7 +101,8 @@ void fsl_msi_free_hwirqs(struct fsl_msi *msi, int offset, int num) static int fsl_msi_free_dt_hwirqs(struct fsl_msi *msi) { - int i, len; + int i; + int len; const u32 *p; bitmap_allocate_region(msi->fsl_msi_bitmap, 0, @@ -138,9 +134,8 @@ static int fsl_msi_free_dt_hwirqs(struct fsl_msi *msi) static int fsl_msi_init_allocator(struct fsl_msi *msi_data) { - int rc, size; - - size = BITS_TO_LONGS(NR_MSI_IRQS) * sizeof(u32); + int rc; + int size = BITS_TO_LONGS(NR_MSI_IRQS) * sizeof(u32); msi_data->fsl_msi_bitmap = kzalloc(size, GFP_KERNEL); @@ -238,7 +233,7 @@ out_free: return rc; } -void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) +static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) { unsigned int cascade_irq; struct fsl_msi *msi_data = fsl_msi; @@ -260,7 +255,7 @@ void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) if (unlikely(desc->status & IRQ_INPROGRESS)) goto unlock; - msir_index = (int)(desc->handler_data); + msir_index = (int)desc->handler_data; if (msir_index >= NR_MSI_REG) cascade_irq = NO_IRQ; @@ -280,12 +275,12 @@ void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) intr_index = ffs(msir_value) - 1; cascade_irq = irq_linear_revmap(msi_data->irqhost, - (msir_index * IRQS_PER_MSI_REG + - intr_index + have_shift)); + msir_index * IRQS_PER_MSI_REG + + intr_index + have_shift); if (cascade_irq != NO_IRQ) generic_handle_irq(cascade_irq); - have_shift += (intr_index + 1); - msir_value = (msir_value >> (intr_index + 1)); + have_shift += intr_index + 1; + msir_value = msir_value >> (intr_index + 1); } desc->status &= ~IRQ_INPROGRESS; @@ -311,7 +306,7 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, int rc; int virt_msir; const u32 *p; - struct fsl_msi_feature *tmp_data; + struct fsl_msi_feature *features = match->data; printk(KERN_DEBUG "Setting up Freescale MSI support\n"); @@ -348,14 +343,12 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, goto error_out; } - tmp_data = (struct fsl_msi_feature *)match->data; - - msi->feature = tmp_data->fsl_pic_ip; + msi->feature = features->fsl_pic_ip; msi->irqhost->host_data = msi; msi->msi_addr_hi = 0x0; - msi->msi_addr_lo = res.start + tmp_data->msiir_offset; + msi->msi_addr_lo = res.start + features->msiir_offset; rc = fsl_msi_init_allocator(msi); if (rc) { diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 52a5f7f41b4a..489ca5a397b1 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -106,15 +106,15 @@ void __init setup_pci_cmd(struct pci_controller *hose) } } -#ifdef CONFIG_PCI_MSI -void __init setup_pci_pcsrbar(struct pci_controller *hose) +static void __init setup_pci_pcsrbar(struct pci_controller *hose) { +#ifdef CONFIG_PCI_MSI phys_addr_t immr_base; immr_base = get_immrbase(); early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, immr_base); -} #endif +} static int fsl_pcie_bus_fixup; @@ -222,9 +222,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary) setup_pci_atmu(hose, &rsrc); /* Setup PEXCSRBAR */ -#ifdef CONFIG_PCI_MSI setup_pci_pcsrbar(hose); -#endif return 0; } -- cgit v1.2.3 From 22fb7d9be593181e2f779cf7a8421703a6be713b Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Thu, 15 May 2008 17:04:57 -0500 Subject: [POWERPC] fsl: Add warning for unrecognized I2C nodes in the device tree Update of_find_i2c_driver in fsl_soc.c to display a warning message if an I2C node in the device tree isn't found in the i2c_devices[] array. Signed-off-by: Timur Tabi Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/fsl_soc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 3a7054e2bb75..a38c364ea260 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -448,6 +448,10 @@ static int __init of_find_i2c_driver(struct device_node *node, return -ENOMEM; return 0; } + + pr_warning("fsl_soc.c: unrecognized i2c node %s\n", + (const char *) of_get_property(node, "compatible", NULL)); + return -ENODEV; } -- cgit v1.2.3 From 64f9b5ee17ee7974d7cc58d75221432d86960ba3 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Thu, 15 May 2008 17:46:10 -0500 Subject: [POWERPC] fsl: Add CS4270 i2c data to fsl_soc.c The i2c_devices[] array in fsl_soc.c lists all the I2C nodes that are supported on Freescale boards. Add an entry for the Cirrus Logic CS4270 so that a new-style CS4270 driver will work. Signed-off-by: Timur Tabi Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/fsl_soc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index a38c364ea260..167523e9e41c 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -433,6 +433,7 @@ static struct i2c_driver_device i2c_devices[] __initdata = { {"dallas,ds1340", "ds1340"}, {"stm,m41t00", "m41t00"}, {"dallas,ds1374", "rtc-ds1374"}, + {"cirrus,cs4270", "cs4270"}, }; static int __init of_find_i2c_driver(struct device_node *node, -- cgit v1.2.3 From e026892c85571e12f11abffde5a90bcc704d663e Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Mon, 2 Jun 2008 15:09:35 -0500 Subject: [POWERPC] fsl: Update fsl_soc to use cell-index property of I2C nodes Currently, fsl_i2c_of_init() uses the order of the I2C adapter nodes in the device tree to enumerate the I2C adapters. Instead, let's check for the cell-index property and use it if it exists. This is handy for device drivers that need to identify the I2C adapters by specific numbers. The Freescale MPC8610 ASoC V2 sound drivers are an example. Signed-off-by: Timur Tabi Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/fsl_soc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 167523e9e41c..14616d5d12d5 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -496,6 +496,8 @@ static int __init fsl_i2c_of_init(void) struct resource r[2]; struct fsl_i2c_platform_data i2c_data; const unsigned char *flags = NULL; + int idx; + const u32 *iprop; memset(&r, 0, sizeof(r)); memset(&i2c_data, 0, sizeof(i2c_data)); @@ -506,7 +508,10 @@ static int __init fsl_i2c_of_init(void) of_irq_to_resource(np, 0, &r[1]); - i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2); + iprop = of_get_property(np, "cell-index", NULL); + idx = iprop ? *iprop : i; + + i2c_dev = platform_device_register_simple("fsl-i2c", idx, r, 2); if (IS_ERR(i2c_dev)) { ret = PTR_ERR(i2c_dev); goto err; @@ -528,7 +533,8 @@ static int __init fsl_i2c_of_init(void) if (ret) goto unreg; - of_register_i2c_devices(np, i++); + of_register_i2c_devices(np, idx); + i++; } return 0; -- cgit v1.2.3 From 5073e7ee8684f3997b3633a2e5fa574027f37891 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 24 May 2008 04:40:00 +1000 Subject: powerpc/mpic: Fix ambiguous else statement This fixes the following warning, introduced by commit 475ca391b490a683d66bf19999a8a7a24913f139 (mpic: Deal with bogus NIRQ in Feature Reporting Register): CC arch/powerpc/sysdev/mpic.o arch/powerpc/sysdev/mpic.c: In function 'mpic_alloc': arch/powerpc/sysdev/mpic.c:1146: warning: suggest explicit braces to avoid ambiguous 'else' Signed-off-by: Anton Vorontsov Acked-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/mpic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index f99f81abbd5c..a281341e4129 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1143,13 +1143,14 @@ struct mpic * __init mpic_alloc(struct device_node *node, greg_feature = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0)); mpic->num_cpus = ((greg_feature & MPIC_GREG_FEATURE_LAST_CPU_MASK) >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1; - if (isu_size == 0) + if (isu_size == 0) { if (flags & MPIC_BROKEN_FRR_NIRQS) mpic->num_sources = mpic->irq_count; else mpic->num_sources = ((greg_feature & MPIC_GREG_FEATURE_LAST_SRC_MASK) >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1; + } /* Map the per-CPU registers */ for (i = 0; i < mpic->num_cpus; i++) { -- cgit v1.2.3 From 84f1c1e08906f2206f2bbdd19e4ff6a0757ff7f8 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 26 May 2008 12:12:30 +1000 Subject: powerpc: Rework ipic_init() so we can avoid freeing the irq_host If we do the call to of_address_to_resource() first, then we don't need to worry about freeing the irq_host (which the code doesn't do currently anyway). Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/ipic.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index 0f2dfb0aaa6a..f95d10ba3b9c 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -725,6 +725,10 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) struct resource res; u32 temp = 0, ret; + ret = of_address_to_resource(node, 0, &res); + if (ret) + return NULL; + ipic = alloc_bootmem(sizeof(struct ipic)); if (ipic == NULL) return NULL; @@ -739,12 +743,6 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) return NULL; } - ret = of_address_to_resource(node, 0, &res); - if (ret) { - of_node_put(node); - return NULL; - } - ipic->regs = ioremap(res.start, res.end - res.start + 1); ipic->irqhost->host_data = ipic; -- cgit v1.2.3 From 2272a55f16c998d916904bba018b0f40f430d744 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 26 May 2008 12:12:31 +1000 Subject: powerpc: Rework qe_ic_init() so we can avoid freeing the irq_host If we do the call to of_address_to_resource() first, then we don't need to worry about freeing the irq_host (which the code doesn't do currently anyway). Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/qe_lib/qe_ic.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c index f59444d3be75..c11b313f015b 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c @@ -329,6 +329,10 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, struct resource res; u32 temp = 0, ret, high_active = 0; + ret = of_address_to_resource(node, 0, &res); + if (ret) + return; + qe_ic = alloc_bootmem(sizeof(struct qe_ic)); if (qe_ic == NULL) return; @@ -342,10 +346,6 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, return; } - ret = of_address_to_resource(node, 0, &res); - if (ret) - return; - qe_ic->regs = ioremap(res.start, res.end - res.start + 1); qe_ic->irqhost->host_data = qe_ic; -- cgit v1.2.3 From 19fc65b5251dfd90312ae0142cc8650cd273e6a6 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 26 May 2008 12:12:32 +1000 Subject: powerpc: Fix irq_alloc_host() reference counting and callers When I changed irq_alloc_host() to take an of_node (52964f87c64e6c6ea671b5bf3030fb1494090a48: "Add an optional device_node pointer to the irq_host"), I botched the reference counting semantics. Stephen pointed out that it's irq_alloc_host()'s business if it needs to take an additional reference to the device_node, the caller shouldn't need to care. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/irq.c | 2 +- arch/powerpc/platforms/cell/axon_msi.c | 2 +- arch/powerpc/platforms/cell/spider-pic.c | 2 +- arch/powerpc/sysdev/cpm1.c | 2 +- arch/powerpc/sysdev/cpm2_pic.c | 2 +- arch/powerpc/sysdev/i8259.c | 2 +- arch/powerpc/sysdev/ipic.c | 6 ++---- arch/powerpc/sysdev/mpic.c | 6 ++---- arch/powerpc/sysdev/qe_lib/qe_ic.c | 6 ++---- arch/powerpc/sysdev/tsi108_pci.c | 3 +-- arch/powerpc/sysdev/uic.c | 6 ++---- 11 files changed, 15 insertions(+), 24 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index b5199752ac60..e9238556ae50 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -498,7 +498,7 @@ struct irq_host *irq_alloc_host(struct device_node *of_node, host->revmap_type = revmap_type; host->inval_irq = inval_irq; host->ops = ops; - host->of_node = of_node; + host->of_node = of_node_get(of_node); if (host->ops->match == NULL) host->ops->match = default_irq_host_match; diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index b43defb9918c..896548ba1ca1 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -365,7 +365,7 @@ static int axon_msi_probe(struct of_device *device, goto out_free_fifo; } - msic->irq_host = irq_alloc_host(of_node_get(dn), IRQ_HOST_MAP_NOMAP, + msic->irq_host = irq_alloc_host(dn, IRQ_HOST_MAP_NOMAP, NR_IRQS, &msic_host_ops, 0); if (!msic->irq_host) { printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n", diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c index 3f4b4aef756d..4e5655624ae8 100644 --- a/arch/powerpc/platforms/cell/spider-pic.c +++ b/arch/powerpc/platforms/cell/spider-pic.c @@ -300,7 +300,7 @@ static void __init spider_init_one(struct device_node *of_node, int chip, panic("spider_pic: can't map registers !"); /* Allocate a host */ - pic->host = irq_alloc_host(of_node_get(of_node), IRQ_HOST_MAP_LINEAR, + pic->host = irq_alloc_host(of_node, IRQ_HOST_MAP_LINEAR, SPIDER_SRC_COUNT, &spider_host_ops, SPIDER_IRQ_INVALID); if (pic->host == NULL) diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index 58292a086c16..661df42830b9 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c @@ -159,7 +159,7 @@ unsigned int cpm_pic_init(void) out_be32(&cpic_reg->cpic_cimr, 0); - cpm_pic_host = irq_alloc_host(of_node_get(np), IRQ_HOST_MAP_LINEAR, + cpm_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, 64, &cpm_pic_host_ops, 64); if (cpm_pic_host == NULL) { printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n"); diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c index 5fe65b2f8f3a..b16ca3ed65d2 100644 --- a/arch/powerpc/sysdev/cpm2_pic.c +++ b/arch/powerpc/sysdev/cpm2_pic.c @@ -266,7 +266,7 @@ void cpm2_pic_init(struct device_node *node) out_be32(&cpm2_intctl->ic_scprrl, 0x05309770); /* create a legacy host */ - cpm2_pic_host = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR, + cpm2_pic_host = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 64, &cpm2_pic_host_ops, 64); if (cpm2_pic_host == NULL) { printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n"); diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c index 216c0f5680d2..a96584ab33dd 100644 --- a/arch/powerpc/sysdev/i8259.c +++ b/arch/powerpc/sysdev/i8259.c @@ -276,7 +276,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr) spin_unlock_irqrestore(&i8259_lock, flags); /* create a legacy host */ - i8259_host = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LEGACY, + i8259_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY, 0, &i8259_host_ops, 0); if (i8259_host == NULL) { printk(KERN_ERR "i8259: failed to allocate irq host !\n"); diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index f95d10ba3b9c..caba1c0be5a7 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -735,13 +735,11 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) memset(ipic, 0, sizeof(struct ipic)); - ipic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR, + ipic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, NR_IPIC_INTS, &ipic_host_ops, 0); - if (ipic->irqhost == NULL) { - of_node_put(node); + if (ipic->irqhost == NULL) return NULL; - } ipic->regs = ioremap(res.start, res.end - res.start + 1); diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index a281341e4129..5788a6ab1254 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1016,13 +1016,11 @@ struct mpic * __init mpic_alloc(struct device_node *node, memset(mpic, 0, sizeof(struct mpic)); mpic->name = name; - mpic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR, + mpic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, isu_size, &mpic_host_ops, flags & MPIC_LARGE_VECTORS ? 2048 : 256); - if (mpic->irqhost == NULL) { - of_node_put(node); + if (mpic->irqhost == NULL) return NULL; - } mpic->irqhost->host_data = mpic; mpic->hc_irq = mpic_irq_chip; diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c index c11b313f015b..63cdf9887f36 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c @@ -339,12 +339,10 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, memset(qe_ic, 0, sizeof(struct qe_ic)); - qe_ic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR, + qe_ic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, NR_QE_IC_INTS, &qe_ic_host_ops, 0); - if (qe_ic->irqhost == NULL) { - of_node_put(node); + if (qe_ic->irqhost == NULL) return; - } qe_ic->regs = ioremap(res.start, res.end - res.start + 1); diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c index ac1a72dc21e5..24e1f5a197ae 100644 --- a/arch/powerpc/sysdev/tsi108_pci.c +++ b/arch/powerpc/sysdev/tsi108_pci.c @@ -426,11 +426,10 @@ void __init tsi108_pci_int_init(struct device_node *node) { DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); - pci_irq_host = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LEGACY, + pci_irq_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY, 0, &pci_irq_host_ops, 0); if (pci_irq_host == NULL) { printk(KERN_ERR "pci_irq_host: failed to allocate irq host !\n"); - of_node_put(node); return; } diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c index 625b275c3795..d35405c59434 100644 --- a/arch/powerpc/sysdev/uic.c +++ b/arch/powerpc/sysdev/uic.c @@ -280,12 +280,10 @@ static struct uic * __init uic_init_one(struct device_node *node) } uic->dcrbase = *dcrreg; - uic->irqhost = irq_alloc_host(of_node_get(node), IRQ_HOST_MAP_LINEAR, + uic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, NR_UIC_INTS, &uic_host_ops, -1); - if (! uic->irqhost) { - of_node_put(node); + if (! uic->irqhost) return NULL; /* FIXME: panic? */ - } uic->irqhost->host_data = uic; -- cgit v1.2.3 From 83ff9dcf375c418ca3b98eb950711525ca1269e2 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 23 May 2008 20:38:54 +0400 Subject: powerpc/sysdev: implement FSL GTM support GTM stands for General-purpose Timers Module and able to generate timer{1,2,3,4} interrupts. These timers are used by the drivers that need time precise interrupts (like for USB transactions scheduling for the Freescale USB Host controller as found in some QE and CPM chips), or these timers could be used as wakeup events from the CPU deep-sleep mode. Things unimplemented: 1. Cascaded (32 bit) timers (1-2, 3-4). This is straightforward to implement when needed, two timers should be marked as "requested" and configured as appropriate. 2. Super-cascaded (64 bit) timers (1-2-3-4). This is also straightforward to implement when needed, all timers should be marked as "requested" and configured as appropriate. Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala --- Documentation/powerpc/booting-without-of.txt | 32 ++ arch/powerpc/Kconfig | 6 + arch/powerpc/sysdev/Makefile | 1 + arch/powerpc/sysdev/fsl_gtm.c | 434 +++++++++++++++++++++++++++ include/asm-powerpc/fsl_gtm.h | 47 +++ 5 files changed, 520 insertions(+) create mode 100644 arch/powerpc/sysdev/fsl_gtm.c create mode 100644 include/asm-powerpc/fsl_gtm.h (limited to 'arch/powerpc/sysdev') diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index 948f6417a40b..8675ebca2cfd 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt @@ -61,6 +61,7 @@ Table of Contents r) Freescale Display Interface Unit s) Freescale on board FPGA t) Freescael MSI interrupt controller + u) Freescale General-purpose Timers Module VII - Marvell Discovery mv64[345]6x System Controller chips 1) The /system-controller node @@ -2907,6 +2908,37 @@ platforms are moved over to use the flattened-device-tree model. interrupt-parent = <&mpic>; }; + u) Freescale General-purpose Timers Module + + Required properties: + - compatible : should be + "fsl,-gtm", "fsl,gtm" for SOC GTMs + "fsl,-qe-gtm", "fsl,qe-gtm", "fsl,gtm" for QE GTMs + "fsl,-cpm2-gtm", "fsl,cpm2-gtm", "fsl,gtm" for CPM2 GTMs + - reg : should contain gtm registers location and length (0x40). + - interrupts : should contain four interrupts. + - interrupt-parent : interrupt source phandle. + - clock-frequency : specifies the frequency driving the timer. + + Example: + + timer@500 { + compatible = "fsl,mpc8360-gtm", "fsl,gtm"; + reg = <0x500 0x40>; + interrupts = <90 8 78 8 84 8 72 8>; + interrupt-parent = <&ipic>; + /* filled by u-boot */ + clock-frequency = <0>; + }; + + timer@440 { + compatible = "fsl,mpc8360-qe-gtm", "fsl,qe-gtm", "fsl,gtm"; + reg = <0x440 0x40>; + interrupts = <12 13 14 15>; + interrupt-parent = <&qeic>; + /* filled by u-boot */ + clock-frequency = <0>; + }; VII - Marvell Discovery mv64[345]6x System Controller chips =========================================================== diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 3934e2659407..2cde4e333fd5 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -538,6 +538,12 @@ config FSL_LBC help Freescale Localbus support +config FSL_GTM + bool + depends on PPC_83xx || QUICC_ENGINE || CPM2 + help + Freescale General-purpose Timers support + # Yes MCA RS/6000s exist but Linux-PPC does not currently support any config MCA bool diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index dd6dff3ffb0f..2bfbb39380e9 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) obj-$(CONFIG_FSL_LBC) += fsl_lbc.o +obj-$(CONFIG_FSL_GTM) += fsl_gtm.o obj-$(CONFIG_RAPIDIO) += fsl_rio.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c new file mode 100644 index 000000000000..714ec02fed2e --- /dev/null +++ b/arch/powerpc/sysdev/fsl_gtm.c @@ -0,0 +1,434 @@ +/* + * Freescale General-purpose Timers Module + * + * Copyright (c) Freescale Semicondutor, Inc. 2006. + * Shlomi Gridish + * Jerry Huang + * Copyright (c) MontaVista Software, Inc. 2008. + * Anton Vorontsov + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define GTCFR_STP(x) ((x) & 1 ? 1 << 5 : 1 << 1) +#define GTCFR_RST(x) ((x) & 1 ? 1 << 4 : 1 << 0) + +#define GTMDR_ICLK_MASK (3 << 1) +#define GTMDR_ICLK_ICAS (0 << 1) +#define GTMDR_ICLK_ICLK (1 << 1) +#define GTMDR_ICLK_SLGO (2 << 1) +#define GTMDR_FRR (1 << 3) +#define GTMDR_ORI (1 << 4) +#define GTMDR_SPS(x) ((x) << 8) + +struct gtm_timers_regs { + u8 gtcfr1; /* Timer 1, Timer 2 global config register */ + u8 res0[0x3]; + u8 gtcfr2; /* Timer 3, timer 4 global config register */ + u8 res1[0xB]; + __be16 gtmdr1; /* Timer 1 mode register */ + __be16 gtmdr2; /* Timer 2 mode register */ + __be16 gtrfr1; /* Timer 1 reference register */ + __be16 gtrfr2; /* Timer 2 reference register */ + __be16 gtcpr1; /* Timer 1 capture register */ + __be16 gtcpr2; /* Timer 2 capture register */ + __be16 gtcnr1; /* Timer 1 counter */ + __be16 gtcnr2; /* Timer 2 counter */ + __be16 gtmdr3; /* Timer 3 mode register */ + __be16 gtmdr4; /* Timer 4 mode register */ + __be16 gtrfr3; /* Timer 3 reference register */ + __be16 gtrfr4; /* Timer 4 reference register */ + __be16 gtcpr3; /* Timer 3 capture register */ + __be16 gtcpr4; /* Timer 4 capture register */ + __be16 gtcnr3; /* Timer 3 counter */ + __be16 gtcnr4; /* Timer 4 counter */ + __be16 gtevr1; /* Timer 1 event register */ + __be16 gtevr2; /* Timer 2 event register */ + __be16 gtevr3; /* Timer 3 event register */ + __be16 gtevr4; /* Timer 4 event register */ + __be16 gtpsr1; /* Timer 1 prescale register */ + __be16 gtpsr2; /* Timer 2 prescale register */ + __be16 gtpsr3; /* Timer 3 prescale register */ + __be16 gtpsr4; /* Timer 4 prescale register */ + u8 res2[0x40]; +} __attribute__ ((packed)); + +struct gtm { + unsigned int clock; + struct gtm_timers_regs __iomem *regs; + struct gtm_timer timers[4]; + spinlock_t lock; + struct list_head list_node; +}; + +static LIST_HEAD(gtms); + +/** + * gtm_get_timer - request GTM timer to use it with the rest of GTM API + * Context: non-IRQ + * + * This function reserves GTM timer for later use. It returns gtm_timer + * structure to use with the rest of GTM API, you should use timer->irq + * to manage timer interrupt. + */ +struct gtm_timer *gtm_get_timer16(void) +{ + struct gtm *gtm = NULL; + int i; + + list_for_each_entry(gtm, >ms, list_node) { + spin_lock_irq(>m->lock); + + for (i = 0; i < ARRAY_SIZE(gtm->timers); i++) { + if (!gtm->timers[i].requested) { + gtm->timers[i].requested = true; + spin_unlock_irq(>m->lock); + return >m->timers[i]; + } + } + + spin_unlock_irq(>m->lock); + } + + if (gtm) + return ERR_PTR(-EBUSY); + return ERR_PTR(-ENODEV); +} +EXPORT_SYMBOL(gtm_get_timer16); + +/** + * gtm_get_specific_timer - request specific GTM timer + * @gtm: specific GTM, pass here GTM's device_node->data + * @timer: specific timer number, Timer1 is 0. + * Context: non-IRQ + * + * This function reserves GTM timer for later use. It returns gtm_timer + * structure to use with the rest of GTM API, you should use timer->irq + * to manage timer interrupt. + */ +struct gtm_timer *gtm_get_specific_timer16(struct gtm *gtm, + unsigned int timer) +{ + struct gtm_timer *ret = ERR_PTR(-EBUSY); + + if (timer > 3) + return ERR_PTR(-EINVAL); + + spin_lock_irq(>m->lock); + + if (gtm->timers[timer].requested) + goto out; + + ret = >m->timers[timer]; + ret->requested = true; + +out: + spin_unlock_irq(>m->lock); + return ret; +} +EXPORT_SYMBOL(gtm_get_specific_timer16); + +/** + * gtm_put_timer16 - release 16 bits GTM timer + * @tmr: pointer to the gtm_timer structure obtained from gtm_get_timer + * Context: any + * + * This function releases GTM timer so others may request it. + */ +void gtm_put_timer16(struct gtm_timer *tmr) +{ + gtm_stop_timer16(tmr); + + spin_lock_irq(&tmr->gtm->lock); + tmr->requested = false; + spin_unlock_irq(&tmr->gtm->lock); +} +EXPORT_SYMBOL(gtm_put_timer16); + +/* + * This is back-end for the exported functions, it's used to reset single + * timer in reference mode. + */ +static int gtm_set_ref_timer16(struct gtm_timer *tmr, int frequency, + int reference_value, bool free_run) +{ + struct gtm *gtm = tmr->gtm; + int num = tmr - >m->timers[0]; + unsigned int prescaler; + u8 iclk = GTMDR_ICLK_ICLK; + u8 psr; + u8 sps; + unsigned long flags; + int max_prescaler = 256 * 256 * 16; + + /* CPM2 doesn't have primary prescaler */ + if (!tmr->gtpsr) + max_prescaler /= 256; + + prescaler = gtm->clock / frequency; + /* + * We have two 8 bit prescalers -- primary and secondary (psr, sps), + * plus "slow go" mode (clk / 16). So, total prescale value is + * 16 * (psr + 1) * (sps + 1). Though, for CPM2 GTMs we losing psr. + */ + if (prescaler > max_prescaler) + return -EINVAL; + + if (prescaler > max_prescaler / 16) { + iclk = GTMDR_ICLK_SLGO; + prescaler /= 16; + } + + if (prescaler <= 256) { + psr = 0; + sps = prescaler - 1; + } else { + psr = 256 - 1; + sps = prescaler / 256 - 1; + } + + spin_lock_irqsave(>m->lock, flags); + + /* + * Properly reset timers: stop, reset, set up prescalers, reference + * value and clear event register. + */ + clrsetbits_8(tmr->gtcfr, ~(GTCFR_STP(num) | GTCFR_RST(num)), + GTCFR_STP(num) | GTCFR_RST(num)); + + setbits8(tmr->gtcfr, GTCFR_STP(num)); + + if (tmr->gtpsr) + out_be16(tmr->gtpsr, psr); + clrsetbits_be16(tmr->gtmdr, 0xFFFF, iclk | GTMDR_SPS(sps) | + GTMDR_ORI | (free_run ? GTMDR_FRR : 0)); + out_be16(tmr->gtcnr, 0); + out_be16(tmr->gtrfr, reference_value); + out_be16(tmr->gtevr, 0xFFFF); + + /* Let it be. */ + clrbits8(tmr->gtcfr, GTCFR_STP(num)); + + spin_unlock_irqrestore(>m->lock, flags); + + return 0; +} + +/** + * gtm_set_timer16 - (re)set 16 bit timer with arbitrary precision + * @tmr: pointer to the gtm_timer structure obtained from gtm_get_timer + * @usec: timer interval in microseconds + * @reload: if set, the timer will reset upon expiry rather than + * continue running free. + * Context: any + * + * This function (re)sets the GTM timer so that it counts up to the requested + * interval value, and fires the interrupt when the value is reached. This + * function will reduce the precision of the timer as needed in order for the + * requested timeout to fit in a 16-bit register. + */ +int gtm_set_timer16(struct gtm_timer *tmr, unsigned long usec, bool reload) +{ + /* quite obvious, frequency which is enough for µSec precision */ + int freq = 1000000; + unsigned int bit; + + bit = fls_long(usec); + if (bit > 15) { + freq >>= bit - 15; + usec >>= bit - 15; + } + + if (!freq) + return -EINVAL; + + return gtm_set_ref_timer16(tmr, freq, usec, reload); +} +EXPORT_SYMBOL(gtm_set_timer16); + +/** + * gtm_set_exact_utimer16 - (re)set 16 bits timer + * @tmr: pointer to the gtm_timer structure obtained from gtm_get_timer + * @usec: timer interval in microseconds + * @reload: if set, the timer will reset upon expiry rather than + * continue running free. + * Context: any + * + * This function (re)sets GTM timer so that it counts up to the requested + * interval value, and fires the interrupt when the value is reached. If reload + * flag was set, timer will also reset itself upon reference value, otherwise + * it continues to increment. + * + * The _exact_ bit in the function name states that this function will not + * crop precision of the "usec" argument, thus usec is limited to 16 bits + * (single timer width). + */ +int gtm_set_exact_timer16(struct gtm_timer *tmr, u16 usec, bool reload) +{ + /* quite obvious, frequency which is enough for µSec precision */ + const int freq = 1000000; + + /* + * We can lower the frequency (and probably power consumption) by + * dividing both frequency and usec by 2 until there is no remainder. + * But we won't bother with this unless savings are measured, so just + * run the timer as is. + */ + + return gtm_set_ref_timer16(tmr, freq, usec, reload); +} +EXPORT_SYMBOL(gtm_set_exact_timer16); + +/** + * gtm_stop_timer16 - stop single timer + * @tmr: pointer to the gtm_timer structure obtained from gtm_get_timer + * Context: any + * + * This function simply stops the GTM timer. + */ +void gtm_stop_timer16(struct gtm_timer *tmr) +{ + struct gtm *gtm = tmr->gtm; + int num = tmr - >m->timers[0]; + unsigned long flags; + + spin_lock_irqsave(>m->lock, flags); + + setbits8(tmr->gtcfr, GTCFR_STP(num)); + out_be16(tmr->gtevr, 0xFFFF); + + spin_unlock_irqrestore(>m->lock, flags); +} +EXPORT_SYMBOL(gtm_stop_timer16); + +/** + * gtm_ack_timer16 - acknowledge timer event (free-run timers only) + * @tmr: pointer to the gtm_timer structure obtained from gtm_get_timer + * @events: events mask to ack + * Context: any + * + * Thus function used to acknowledge timer interrupt event, use it inside the + * interrupt handler. + */ +void gtm_ack_timer16(struct gtm_timer *tmr, u16 events) +{ + out_be16(tmr->gtevr, events); +} +EXPORT_SYMBOL(gtm_ack_timer16); + +static void __init gtm_set_shortcuts(struct device_node *np, + struct gtm_timer *timers, + struct gtm_timers_regs __iomem *regs) +{ + /* + * Yeah, I don't like this either, but timers' registers a bit messed, + * so we have to provide shortcuts to write timer independent code. + * Alternative option is to create gt*() accessors, but that will be + * even uglier and cryptic. + */ + timers[0].gtcfr = ®s->gtcfr1; + timers[0].gtmdr = ®s->gtmdr1; + timers[0].gtcnr = ®s->gtcnr1; + timers[0].gtrfr = ®s->gtrfr1; + timers[0].gtevr = ®s->gtevr1; + + timers[1].gtcfr = ®s->gtcfr1; + timers[1].gtmdr = ®s->gtmdr2; + timers[1].gtcnr = ®s->gtcnr2; + timers[1].gtrfr = ®s->gtrfr2; + timers[1].gtevr = ®s->gtevr2; + + timers[2].gtcfr = ®s->gtcfr2; + timers[2].gtmdr = ®s->gtmdr3; + timers[2].gtcnr = ®s->gtcnr3; + timers[2].gtrfr = ®s->gtrfr3; + timers[2].gtevr = ®s->gtevr3; + + timers[3].gtcfr = ®s->gtcfr2; + timers[3].gtmdr = ®s->gtmdr4; + timers[3].gtcnr = ®s->gtcnr4; + timers[3].gtrfr = ®s->gtrfr4; + timers[3].gtevr = ®s->gtevr4; + + /* CPM2 doesn't have primary prescaler */ + if (!of_device_is_compatible(np, "fsl,cpm2-gtm")) { + timers[0].gtpsr = ®s->gtpsr1; + timers[1].gtpsr = ®s->gtpsr2; + timers[2].gtpsr = ®s->gtpsr3; + timers[3].gtpsr = ®s->gtpsr4; + } +} + +static int __init fsl_gtm_init(void) +{ + struct device_node *np; + + for_each_compatible_node(np, NULL, "fsl,gtm") { + int i; + struct gtm *gtm; + const u32 *clock; + int size; + + gtm = kzalloc(sizeof(*gtm), GFP_KERNEL); + if (!gtm) { + pr_err("%s: unable to allocate memory\n", + np->full_name); + continue; + } + + spin_lock_init(>m->lock); + + clock = of_get_property(np, "clock-frequency", &size); + if (!clock || size != sizeof(*clock)) { + pr_err("%s: no clock-frequency\n", np->full_name); + goto err; + } + gtm->clock = *clock; + + for (i = 0; i < ARRAY_SIZE(gtm->timers); i++) { + int ret; + struct resource irq; + + ret = of_irq_to_resource(np, i, &irq); + if (ret == NO_IRQ) { + pr_err("%s: not enough interrupts specified\n", + np->full_name); + goto err; + } + gtm->timers[i].irq = irq.start; + gtm->timers[i].gtm = gtm; + } + + gtm->regs = of_iomap(np, 0); + if (!gtm->regs) { + pr_err("%s: unable to iomap registers\n", + np->full_name); + goto err; + } + + gtm_set_shortcuts(np, gtm->timers, gtm->regs); + list_add(>m->list_node, >ms); + + /* We don't want to lose the node and its ->data */ + np->data = gtm; + of_node_get(np); + + continue; +err: + kfree(gtm); + } + return 0; +} +arch_initcall(fsl_gtm_init); diff --git a/include/asm-powerpc/fsl_gtm.h b/include/asm-powerpc/fsl_gtm.h new file mode 100644 index 000000000000..8e8c9b5032d3 --- /dev/null +++ b/include/asm-powerpc/fsl_gtm.h @@ -0,0 +1,47 @@ +/* + * Freescale General-purpose Timers Module + * + * Copyright (c) Freescale Semicondutor, Inc. 2006. + * Shlomi Gridish + * Jerry Huang + * Copyright (c) MontaVista Software, Inc. 2008. + * Anton Vorontsov + * + * 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. + */ + +#ifndef __ASM_FSL_GTM_H +#define __ASM_FSL_GTM_H + +#include + +struct gtm; + +struct gtm_timer { + unsigned int irq; + + struct gtm *gtm; + bool requested; + u8 __iomem *gtcfr; + __be16 __iomem *gtmdr; + __be16 __iomem *gtpsr; + __be16 __iomem *gtcnr; + __be16 __iomem *gtrfr; + __be16 __iomem *gtevr; +}; + +extern struct gtm_timer *gtm_get_timer16(void); +extern struct gtm_timer *gtm_get_specific_timer16(struct gtm *gtm, + unsigned int timer); +extern void gtm_put_timer16(struct gtm_timer *tmr); +extern int gtm_set_timer16(struct gtm_timer *tmr, unsigned long usec, + bool reload); +extern int gtm_set_exact_timer16(struct gtm_timer *tmr, u16 usec, + bool reload); +extern void gtm_stop_timer16(struct gtm_timer *tmr); +extern void gtm_ack_timer16(struct gtm_timer *tmr, u16 events); + +#endif /* __ASM_FSL_GTM_H */ -- cgit v1.2.3 From 5e41486c408eb4206aee09303631427f57771691 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 23 May 2008 20:38:56 +0400 Subject: powerpc/QE: add support for QE USB clocks routing This patch adds a function to the qe_lib to setup QE USB clocks routing. To setup clocks safely, cmxgcr register needs locking, so I just reused ucc_lock since it was used only to protect cmxgcr. The idea behind placing clocks routing functions into the qe_lib is that later we'll hopefully switch to the generic Linux Clock API, thus, for example, FHCI driver may be used for QE and CPM chips without nasty #ifdefs. This patch also fixes QE_USB_RESTART_TX command definition in the qe.h. Signed-off-by: Anton Vorontsov Acked-By: Timur Tabi Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/qe_lib/Kconfig | 4 +++ arch/powerpc/sysdev/qe_lib/Makefile | 1 + arch/powerpc/sysdev/qe_lib/ucc.c | 7 +++-- arch/powerpc/sysdev/qe_lib/usb.c | 55 +++++++++++++++++++++++++++++++++++++ include/asm-powerpc/qe.h | 23 +++++++++++++++- 5 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 arch/powerpc/sysdev/qe_lib/usb.c (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig index adc66212a419..76ffbc48d4b9 100644 --- a/arch/powerpc/sysdev/qe_lib/Kconfig +++ b/arch/powerpc/sysdev/qe_lib/Kconfig @@ -20,3 +20,7 @@ config UCC bool default y if UCC_FAST || UCC_SLOW +config QE_USB + bool + help + QE USB Host Controller support diff --git a/arch/powerpc/sysdev/qe_lib/Makefile b/arch/powerpc/sysdev/qe_lib/Makefile index 874fe1a5b1cf..e9ff8884f74a 100644 --- a/arch/powerpc/sysdev/qe_lib/Makefile +++ b/arch/powerpc/sysdev/qe_lib/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_QUICC_ENGINE)+= qe.o qe_ic.o qe_io.o obj-$(CONFIG_UCC) += ucc.o obj-$(CONFIG_UCC_SLOW) += ucc_slow.o obj-$(CONFIG_UCC_FAST) += ucc_fast.o +obj-$(CONFIG_QE_USB) += usb.o diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c index 0e348d9af8a6..d3c7f5af9bc8 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc.c +++ b/arch/powerpc/sysdev/qe_lib/ucc.c @@ -26,7 +26,8 @@ #include #include -static DEFINE_SPINLOCK(ucc_lock); +DEFINE_SPINLOCK(cmxgcr_lock); +EXPORT_SYMBOL(cmxgcr_lock); int ucc_set_qe_mux_mii_mng(unsigned int ucc_num) { @@ -35,10 +36,10 @@ int ucc_set_qe_mux_mii_mng(unsigned int ucc_num) if (ucc_num > UCC_MAX_NUM - 1) return -EINVAL; - spin_lock_irqsave(&ucc_lock, flags); + spin_lock_irqsave(&cmxgcr_lock, flags); clrsetbits_be32(&qe_immr->qmx.cmxgcr, QE_CMXGCR_MII_ENET_MNG, ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT); - spin_unlock_irqrestore(&ucc_lock, flags); + spin_unlock_irqrestore(&cmxgcr_lock, flags); return 0; } diff --git a/arch/powerpc/sysdev/qe_lib/usb.c b/arch/powerpc/sysdev/qe_lib/usb.c new file mode 100644 index 000000000000..8105462078eb --- /dev/null +++ b/arch/powerpc/sysdev/qe_lib/usb.c @@ -0,0 +1,55 @@ +/* + * QE USB routines + * + * Copyright (c) Freescale Semicondutor, Inc. 2006. + * Shlomi Gridish + * Jerry Huang + * Copyright (c) MontaVista Software, Inc. 2008. + * Anton Vorontsov + * + * 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. + */ + +#include +#include +#include +#include +#include + +int qe_usb_clock_set(enum qe_clock clk, int rate) +{ + struct qe_mux __iomem *mux = &qe_immr->qmx; + unsigned long flags; + u32 val; + + switch (clk) { + case QE_CLK3: val = QE_CMXGCR_USBCS_CLK3; break; + case QE_CLK5: val = QE_CMXGCR_USBCS_CLK5; break; + case QE_CLK7: val = QE_CMXGCR_USBCS_CLK7; break; + case QE_CLK9: val = QE_CMXGCR_USBCS_CLK9; break; + case QE_CLK13: val = QE_CMXGCR_USBCS_CLK13; break; + case QE_CLK17: val = QE_CMXGCR_USBCS_CLK17; break; + case QE_CLK19: val = QE_CMXGCR_USBCS_CLK19; break; + case QE_CLK21: val = QE_CMXGCR_USBCS_CLK21; break; + case QE_BRG9: val = QE_CMXGCR_USBCS_BRG9; break; + case QE_BRG10: val = QE_CMXGCR_USBCS_BRG10; break; + default: + pr_err("%s: requested unknown clock %d\n", __func__, clk); + return -EINVAL; + } + + if (qe_clock_is_brg(clk)) + qe_setbrg(clk, rate, 1); + + spin_lock_irqsave(&cmxgcr_lock, flags); + + clrsetbits_be32(&mux->cmxgcr, QE_CMXGCR_USBCS, val); + + spin_unlock_irqrestore(&cmxgcr_lock, flags); + + return 0; +} +EXPORT_SYMBOL(qe_usb_clock_set); diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h index c3be6e2e1490..d217288ec6bf 100644 --- a/include/asm-powerpc/qe.h +++ b/include/asm-powerpc/qe.h @@ -16,6 +16,7 @@ #define _ASM_POWERPC_QE_H #ifdef __KERNEL__ +#include #include #define QE_NUM_OF_SNUM 28 @@ -74,6 +75,13 @@ enum qe_clock { QE_CLK_DUMMY }; +static inline bool qe_clock_is_brg(enum qe_clock clk) +{ + return clk >= QE_BRG1 && clk <= QE_BRG16; +} + +extern spinlock_t cmxgcr_lock; + /* Export QE common operations */ extern void qe_reset(void); extern int par_io_init(struct device_node *np); @@ -156,6 +164,9 @@ int qe_upload_firmware(const struct qe_firmware *firmware); /* Obtain information on the uploaded firmware */ struct qe_firmware_info *qe_get_firmware_info(void); +/* QE USB */ +int qe_usb_clock_set(enum qe_clock clk, int rate); + /* Buffer descriptors */ struct qe_bd { __be16 status; @@ -254,6 +265,16 @@ enum comm_dir { #define QE_CMXGCR_MII_ENET_MNG 0x00007000 #define QE_CMXGCR_MII_ENET_MNG_SHIFT 12 #define QE_CMXGCR_USBCS 0x0000000f +#define QE_CMXGCR_USBCS_CLK3 0x1 +#define QE_CMXGCR_USBCS_CLK5 0x2 +#define QE_CMXGCR_USBCS_CLK7 0x3 +#define QE_CMXGCR_USBCS_CLK9 0x4 +#define QE_CMXGCR_USBCS_CLK13 0x5 +#define QE_CMXGCR_USBCS_CLK17 0x6 +#define QE_CMXGCR_USBCS_CLK19 0x7 +#define QE_CMXGCR_USBCS_CLK21 0x8 +#define QE_CMXGCR_USBCS_BRG9 0x9 +#define QE_CMXGCR_USBCS_BRG10 0xa /* QE CECR Commands. */ @@ -283,7 +304,7 @@ enum comm_dir { #define QE_HPAC_START_TX 0x0000060b #define QE_HPAC_START_RX 0x0000070b #define QE_USB_STOP_TX 0x0000000a -#define QE_USB_RESTART_TX 0x0000000b +#define QE_USB_RESTART_TX 0x0000000c #define QE_QMC_STOP_TX 0x0000000c #define QE_QMC_STOP_RX 0x0000000d #define QE_SS7_SU_FIL_RESET 0x0000000e -- cgit v1.2.3 From 9572653ee01a2134ae3a1d7aa29ce9d026a6afe9 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 23 May 2008 20:38:58 +0400 Subject: powerpc/QE: prepare QE PIO code for GPIO LIB support - split and export __par_io_config_pin() out of par_io_config_pin(), so we could use the prefixed version with GPIO LIB API; - rename struct port_regs to qe_pio_regs, and place it into qe.h; - rename #define NUM_OF_PINS to QE_PIO_PINS, and place it into qe.h. Signed-off-by: Anton Vorontsov Acked-By: Timur Tabi Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/qe_lib/qe_io.c | 94 ++++++++++++++++++-------------------- include/asm-powerpc/qe.h | 19 ++++++++ 2 files changed, 64 insertions(+), 49 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/arch/powerpc/sysdev/qe_lib/qe_io.c index 93916a48afec..7c87460179ef 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_io.c +++ b/arch/powerpc/sysdev/qe_lib/qe_io.c @@ -28,21 +28,7 @@ #undef DEBUG -#define NUM_OF_PINS 32 - -struct port_regs { - __be32 cpodr; /* Open drain register */ - __be32 cpdata; /* Data register */ - __be32 cpdir1; /* Direction register */ - __be32 cpdir2; /* Direction register */ - __be32 cppar1; /* Pin assignment register */ - __be32 cppar2; /* Pin assignment register */ -#ifdef CONFIG_PPC_85xx - u8 pad[8]; -#endif -}; - -static struct port_regs __iomem *par_io; +static struct qe_pio_regs __iomem *par_io; static int num_par_io_ports = 0; int par_io_init(struct device_node *np) @@ -64,69 +50,79 @@ int par_io_init(struct device_node *np) return 0; } -int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain, - int assignment, int has_irq) +void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, int dir, + int open_drain, int assignment, int has_irq) { - u32 pin_mask1bit, pin_mask2bits, new_mask2bits, tmp_val; - - if (!par_io) - return -1; + u32 pin_mask1bit; + u32 pin_mask2bits; + u32 new_mask2bits; + u32 tmp_val; /* calculate pin location for single and 2 bits information */ - pin_mask1bit = (u32) (1 << (NUM_OF_PINS - (pin + 1))); + pin_mask1bit = (u32) (1 << (QE_PIO_PINS - (pin + 1))); /* Set open drain, if required */ - tmp_val = in_be32(&par_io[port].cpodr); + tmp_val = in_be32(&par_io->cpodr); if (open_drain) - out_be32(&par_io[port].cpodr, pin_mask1bit | tmp_val); + out_be32(&par_io->cpodr, pin_mask1bit | tmp_val); else - out_be32(&par_io[port].cpodr, ~pin_mask1bit & tmp_val); + out_be32(&par_io->cpodr, ~pin_mask1bit & tmp_val); /* define direction */ - tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ? - in_be32(&par_io[port].cpdir2) : - in_be32(&par_io[port].cpdir1); + tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ? + in_be32(&par_io->cpdir2) : + in_be32(&par_io->cpdir1); /* get all bits mask for 2 bit per port */ - pin_mask2bits = (u32) (0x3 << (NUM_OF_PINS - - (pin % (NUM_OF_PINS / 2) + 1) * 2)); + pin_mask2bits = (u32) (0x3 << (QE_PIO_PINS - + (pin % (QE_PIO_PINS / 2) + 1) * 2)); /* Get the final mask we need for the right definition */ - new_mask2bits = (u32) (dir << (NUM_OF_PINS - - (pin % (NUM_OF_PINS / 2) + 1) * 2)); + new_mask2bits = (u32) (dir << (QE_PIO_PINS - + (pin % (QE_PIO_PINS / 2) + 1) * 2)); /* clear and set 2 bits mask */ - if (pin > (NUM_OF_PINS / 2) - 1) { - out_be32(&par_io[port].cpdir2, + if (pin > (QE_PIO_PINS / 2) - 1) { + out_be32(&par_io->cpdir2, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; - out_be32(&par_io[port].cpdir2, new_mask2bits | tmp_val); + out_be32(&par_io->cpdir2, new_mask2bits | tmp_val); } else { - out_be32(&par_io[port].cpdir1, + out_be32(&par_io->cpdir1, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; - out_be32(&par_io[port].cpdir1, new_mask2bits | tmp_val); + out_be32(&par_io->cpdir1, new_mask2bits | tmp_val); } /* define pin assignment */ - tmp_val = (pin > (NUM_OF_PINS / 2) - 1) ? - in_be32(&par_io[port].cppar2) : - in_be32(&par_io[port].cppar1); + tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ? + in_be32(&par_io->cppar2) : + in_be32(&par_io->cppar1); - new_mask2bits = (u32) (assignment << (NUM_OF_PINS - - (pin % (NUM_OF_PINS / 2) + 1) * 2)); + new_mask2bits = (u32) (assignment << (QE_PIO_PINS - + (pin % (QE_PIO_PINS / 2) + 1) * 2)); /* clear and set 2 bits mask */ - if (pin > (NUM_OF_PINS / 2) - 1) { - out_be32(&par_io[port].cppar2, + if (pin > (QE_PIO_PINS / 2) - 1) { + out_be32(&par_io->cppar2, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; - out_be32(&par_io[port].cppar2, new_mask2bits | tmp_val); + out_be32(&par_io->cppar2, new_mask2bits | tmp_val); } else { - out_be32(&par_io[port].cppar1, + out_be32(&par_io->cppar1, ~pin_mask2bits & tmp_val); tmp_val &= ~pin_mask2bits; - out_be32(&par_io[port].cppar1, new_mask2bits | tmp_val); + out_be32(&par_io->cppar1, new_mask2bits | tmp_val); } +} +EXPORT_SYMBOL(__par_io_config_pin); + +int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain, + int assignment, int has_irq) +{ + if (!par_io || port >= num_par_io_ports) + return -EINVAL; + __par_io_config_pin(&par_io[port], pin, dir, open_drain, assignment, + has_irq); return 0; } EXPORT_SYMBOL(par_io_config_pin); @@ -137,10 +133,10 @@ int par_io_data_set(u8 port, u8 pin, u8 val) if (port >= num_par_io_ports) return -EINVAL; - if (pin >= NUM_OF_PINS) + if (pin >= QE_PIO_PINS) return -EINVAL; /* calculate pin location */ - pin_mask = (u32) (1 << (NUM_OF_PINS - 1 - pin)); + pin_mask = (u32) (1 << (QE_PIO_PINS - 1 - pin)); tmp_val = in_be32(&par_io[port].cpdata); diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h index d217288ec6bf..c4523acad48b 100644 --- a/include/asm-powerpc/qe.h +++ b/include/asm-powerpc/qe.h @@ -84,8 +84,27 @@ extern spinlock_t cmxgcr_lock; /* Export QE common operations */ extern void qe_reset(void); + +/* QE PIO */ +#define QE_PIO_PINS 32 + +struct qe_pio_regs { + __be32 cpodr; /* Open drain register */ + __be32 cpdata; /* Data register */ + __be32 cpdir1; /* Direction register */ + __be32 cpdir2; /* Direction register */ + __be32 cppar1; /* Pin assignment register */ + __be32 cppar2; /* Pin assignment register */ +#ifdef CONFIG_PPC_85xx + u8 pad[8]; +#endif +}; + extern int par_io_init(struct device_node *np); extern int par_io_of_config(struct device_node *np); +extern void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, + int dir, int open_drain, int assignment, + int has_irq); extern int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain, int assignment, int has_irq); extern int par_io_data_set(u8 port, u8 pin, u8 val); -- cgit v1.2.3 From 32def337aafee0bc65eb58d5b1b3617525eb7fb7 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Mon, 19 May 2008 21:47:05 +0400 Subject: powerpc/QE: implement support for the GPIO LIB API This is needed to access QE GPIOs via Linux GPIO API. Signed-off-by: Anton Vorontsov Acked-By: Timur Tabi Signed-off-by: Kumar Gala --- Documentation/powerpc/booting-without-of.txt | 27 +++++ arch/powerpc/sysdev/qe_lib/Kconfig | 9 ++ arch/powerpc/sysdev/qe_lib/Makefile | 1 + arch/powerpc/sysdev/qe_lib/gpio.c | 146 +++++++++++++++++++++++++++ include/asm-powerpc/qe.h | 3 + 5 files changed, 186 insertions(+) create mode 100644 arch/powerpc/sysdev/qe_lib/gpio.c (limited to 'arch/powerpc/sysdev') diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index 8675ebca2cfd..b68684d39f96 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt @@ -1736,6 +1736,33 @@ platforms are moved over to use the flattened-device-tree model. ...... }; + Note that "par_io" nodes are obsolete, and should not be used for + the new device trees. Instead, each Par I/O bank should be represented + via its own gpio-controller node: + + Required properties: + - #gpio-cells : should be "2". + - compatible : should be "fsl,-qe-pario-bank", + "fsl,mpc8323-qe-pario-bank". + - reg : offset to the register set and its length. + - gpio-controller : node to identify gpio controllers. + + Example: + qe_pio_a: gpio-controller@1400 { + #gpio-cells = <2>; + compatible = "fsl,mpc8360-qe-pario-bank", + "fsl,mpc8323-qe-pario-bank"; + reg = <0x1400 0x18>; + gpio-controller; + }; + + qe_pio_e: gpio-controller@1460 { + #gpio-cells = <2>; + compatible = "fsl,mpc8360-qe-pario-bank", + "fsl,mpc8323-qe-pario-bank"; + reg = <0x1460 0x18>; + gpio-controller; + }; vi) Pin configuration nodes diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig index 76ffbc48d4b9..4bb18f57901e 100644 --- a/arch/powerpc/sysdev/qe_lib/Kconfig +++ b/arch/powerpc/sysdev/qe_lib/Kconfig @@ -24,3 +24,12 @@ config QE_USB bool help QE USB Host Controller support + +config QE_GPIO + bool "QE GPIO support" + depends on QUICC_ENGINE + select GENERIC_GPIO + select HAVE_GPIO_LIB + help + Say Y here if you're going to use hardware that connects to the + QE GPIOs. diff --git a/arch/powerpc/sysdev/qe_lib/Makefile b/arch/powerpc/sysdev/qe_lib/Makefile index e9ff8884f74a..f1855c185291 100644 --- a/arch/powerpc/sysdev/qe_lib/Makefile +++ b/arch/powerpc/sysdev/qe_lib/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_UCC) += ucc.o obj-$(CONFIG_UCC_SLOW) += ucc_slow.o obj-$(CONFIG_UCC_FAST) += ucc_fast.o obj-$(CONFIG_QE_USB) += usb.o +obj-$(CONFIG_QE_GPIO) += gpio.o diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c new file mode 100644 index 000000000000..c712e245dc4c --- /dev/null +++ b/arch/powerpc/sysdev/qe_lib/gpio.c @@ -0,0 +1,146 @@ +/* + * QUICC Engine GPIOs + * + * Copyright (c) MontaVista Software, Inc. 2008. + * + * Author: Anton Vorontsov + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +struct qe_gpio_chip { + struct of_mm_gpio_chip mm_gc; + spinlock_t lock; + + /* shadowed data register to clear/set bits safely */ + u32 cpdata; +}; + +static inline struct qe_gpio_chip * +to_qe_gpio_chip(struct of_mm_gpio_chip *mm_gc) +{ + return container_of(mm_gc, struct qe_gpio_chip, mm_gc); +} + +static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc) +{ + struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc); + struct qe_pio_regs __iomem *regs = mm_gc->regs; + + qe_gc->cpdata = in_be32(®s->cpdata); +} + +static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct qe_pio_regs __iomem *regs = mm_gc->regs; + u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio); + + return in_be32(®s->cpdata) & pin_mask; +} + +static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc); + struct qe_pio_regs __iomem *regs = mm_gc->regs; + unsigned long flags; + u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio); + + spin_lock_irqsave(&qe_gc->lock, flags); + + if (val) + qe_gc->cpdata |= pin_mask; + else + qe_gc->cpdata &= ~pin_mask; + + out_be32(®s->cpdata, qe_gc->cpdata); + + spin_unlock_irqrestore(&qe_gc->lock, flags); +} + +static int qe_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc); + unsigned long flags; + + spin_lock_irqsave(&qe_gc->lock, flags); + + __par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_IN, 0, 0, 0); + + spin_unlock_irqrestore(&qe_gc->lock, flags); + + return 0; +} + +static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc); + unsigned long flags; + + spin_lock_irqsave(&qe_gc->lock, flags); + + __par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_OUT, 0, 0, 0); + + spin_unlock_irqrestore(&qe_gc->lock, flags); + + qe_gpio_set(gc, gpio, val); + + return 0; +} + +void __init qe_add_gpiochips(void) +{ + struct device_node *np; + + for_each_compatible_node(np, NULL, "fsl,mpc8323-qe-pario-bank") { + int ret; + struct qe_gpio_chip *qe_gc; + struct of_mm_gpio_chip *mm_gc; + struct of_gpio_chip *of_gc; + struct gpio_chip *gc; + + qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL); + if (!qe_gc) { + ret = -ENOMEM; + goto err; + } + + spin_lock_init(&qe_gc->lock); + + mm_gc = &qe_gc->mm_gc; + of_gc = &mm_gc->of_gc; + gc = &of_gc->gc; + + mm_gc->save_regs = qe_gpio_save_regs; + of_gc->gpio_cells = 2; + gc->ngpio = QE_PIO_PINS; + gc->direction_input = qe_gpio_dir_in; + gc->direction_output = qe_gpio_dir_out; + gc->get = qe_gpio_get; + gc->set = qe_gpio_set; + + ret = of_mm_gpiochip_add(np, mm_gc); + if (ret) + goto err; + continue; +err: + pr_err("%s: registration failed with status %d\n", + np->full_name, ret); + kfree(qe_gc); + /* try others anyway */ + } +} diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h index c4523acad48b..01e3c70b93ab 100644 --- a/include/asm-powerpc/qe.h +++ b/include/asm-powerpc/qe.h @@ -100,8 +100,11 @@ struct qe_pio_regs { #endif }; +extern void __init qe_add_gpiochips(void); extern int par_io_init(struct device_node *np); extern int par_io_of_config(struct device_node *np); +#define QE_PIO_DIR_IN 2 +#define QE_PIO_DIR_OUT 1 extern void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, int dir, int open_drain, int assignment, int has_irq); -- cgit v1.2.3 From 5093bb965a163fe288c3e5db0275165f86c895c2 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 23 May 2008 20:39:06 +0400 Subject: powerpc/QE: switch to the cpm_muram implementation This is very trivial patch. We're transitioning to the cpm_muram_* calls. That's it. Less trivial changes: - BD_SC_* defines were defined in the cpm.h and qe.h, so to avoid redefines we remove BD_SC from the qe.h and use cpm.h along with cpm_muram_* prototypes; - qe_muram_dump was unused and thus removed; - added some code to the cpm_common.c to support legacy QE bindings (data-only node name). - For convenience, define qe_* calls to cpm_*. So drivers need not to be changed. Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/Makefile | 1 + arch/powerpc/sysdev/cpm_common.c | 16 +++++-- arch/powerpc/sysdev/qe_lib/qe.c | 92 ---------------------------------------- include/asm-powerpc/cpm.h | 1 + include/asm-powerpc/qe.h | 36 ++++------------ 5 files changed, 23 insertions(+), 123 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 2bfbb39380e9..16a0ed28eb00 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -42,6 +42,7 @@ endif ifeq ($(ARCH),powerpc) obj-$(CONFIG_CPM) += cpm_common.o obj-$(CONFIG_CPM2) += cpm2.o cpm2_pic.o +obj-$(CONFIG_QUICC_ENGINE) += cpm_common.o obj-$(CONFIG_PPC_DCR) += dcr.o obj-$(CONFIG_8xx) += mpc8xx_pic.o cpm1.o obj-$(CONFIG_UCODE_PATCH) += micropatch.o diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index cb7df2dce44f..9b75d164bdf9 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c @@ -85,9 +85,13 @@ int __init cpm_muram_init(void) np = of_find_compatible_node(NULL, NULL, "fsl,cpm-muram-data"); if (!np) { - printk(KERN_ERR "Cannot find CPM muram data node"); - ret = -ENODEV; - goto out; + /* try legacy bindings */ + np = of_find_node_by_name(NULL, "data-only"); + if (!np) { + printk(KERN_ERR "Cannot find CPM muram data node"); + ret = -ENODEV; + goto out; + } } muram_pbase = of_translate_address(np, zero); @@ -189,6 +193,12 @@ void __iomem *cpm_muram_addr(unsigned long offset) } EXPORT_SYMBOL(cpm_muram_addr); +unsigned long cpm_muram_offset(void __iomem *addr) +{ + return addr - (void __iomem *)muram_vbase; +} +EXPORT_SYMBOL(cpm_muram_offset); + /** * cpm_muram_dma - turn a muram virtual address into a DMA address * @offset: virtual address from cpm_muram_addr() to convert diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index cff550eec7e8..28e05df952de 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -35,7 +35,6 @@ #include static void qe_snums_init(void); -static void qe_muram_init(void); static int qe_sdma_init(void); static DEFINE_SPINLOCK(qe_lock); @@ -325,97 +324,6 @@ static int qe_sdma_init(void) return 0; } -/* - * muram_alloc / muram_free bits. - */ -static DEFINE_SPINLOCK(qe_muram_lock); - -/* 16 blocks should be enough to satisfy all requests - * until the memory subsystem goes up... */ -static rh_block_t qe_boot_muram_rh_block[16]; -static rh_info_t qe_muram_info; - -static void qe_muram_init(void) -{ - struct device_node *np; - const u32 *address; - u64 size; - unsigned int flags; - - /* initialize the info header */ - rh_init(&qe_muram_info, 1, - sizeof(qe_boot_muram_rh_block) / - sizeof(qe_boot_muram_rh_block[0]), qe_boot_muram_rh_block); - - /* Attach the usable muram area */ - /* XXX: This is a subset of the available muram. It - * varies with the processor and the microcode patches activated. - */ - np = of_find_compatible_node(NULL, NULL, "fsl,qe-muram-data"); - if (!np) { - np = of_find_node_by_name(NULL, "data-only"); - if (!np) { - WARN_ON(1); - return; - } - } - - address = of_get_address(np, 0, &size, &flags); - WARN_ON(!address); - - of_node_put(np); - if (address) - rh_attach_region(&qe_muram_info, *address, (int)size); -} - -/* This function returns an index into the MURAM area. - */ -unsigned long qe_muram_alloc(int size, int align) -{ - unsigned long start; - unsigned long flags; - - spin_lock_irqsave(&qe_muram_lock, flags); - start = rh_alloc_align(&qe_muram_info, size, align, "QE"); - spin_unlock_irqrestore(&qe_muram_lock, flags); - - return start; -} -EXPORT_SYMBOL(qe_muram_alloc); - -int qe_muram_free(unsigned long offset) -{ - int ret; - unsigned long flags; - - spin_lock_irqsave(&qe_muram_lock, flags); - ret = rh_free(&qe_muram_info, offset); - spin_unlock_irqrestore(&qe_muram_lock, flags); - - return ret; -} -EXPORT_SYMBOL(qe_muram_free); - -/* not sure if this is ever needed */ -unsigned long qe_muram_alloc_fixed(unsigned long offset, int size) -{ - unsigned long start; - unsigned long flags; - - spin_lock_irqsave(&qe_muram_lock, flags); - start = rh_alloc_fixed(&qe_muram_info, offset, size, "commproc"); - spin_unlock_irqrestore(&qe_muram_lock, flags); - - return start; -} -EXPORT_SYMBOL(qe_muram_alloc_fixed); - -void qe_muram_dump(void) -{ - rh_dump(&qe_muram_info); -} -EXPORT_SYMBOL(qe_muram_dump); - /* The maximum number of RISCs we support */ #define MAX_QE_RISC 2 diff --git a/include/asm-powerpc/cpm.h b/include/asm-powerpc/cpm.h index ede38ffe466a..63a55337c2de 100644 --- a/include/asm-powerpc/cpm.h +++ b/include/asm-powerpc/cpm.h @@ -96,6 +96,7 @@ unsigned long cpm_muram_alloc(unsigned long size, unsigned long align); int cpm_muram_free(unsigned long offset); unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); void __iomem *cpm_muram_addr(unsigned long offset); +unsigned long cpm_muram_offset(void __iomem *addr); dma_addr_t cpm_muram_dma(void __iomem *addr); int cpm_command(u32 command, u8 opcode); diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h index 01e3c70b93ab..80807fd6a706 100644 --- a/include/asm-powerpc/qe.h +++ b/include/asm-powerpc/qe.h @@ -17,6 +17,7 @@ #ifdef __KERNEL__ #include +#include #include #define QE_NUM_OF_SNUM 28 @@ -119,20 +120,13 @@ unsigned int qe_get_brg_clk(void); int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier); int qe_get_snum(void); void qe_put_snum(u8 snum); -unsigned long qe_muram_alloc(int size, int align); -int qe_muram_free(unsigned long offset); -unsigned long qe_muram_alloc_fixed(unsigned long offset, int size); -void qe_muram_dump(void); - -static inline void __iomem *qe_muram_addr(unsigned long offset) -{ - return (void __iomem *)&qe_immr->muram[offset]; -} - -static inline unsigned long qe_muram_offset(void __iomem *addr) -{ - return addr - (void __iomem *)qe_immr->muram; -} +/* we actually use cpm_muram implementation, define this for convenience */ +#define qe_muram_init cpm_muram_init +#define qe_muram_alloc cpm_muram_alloc +#define qe_muram_alloc_fixed cpm_muram_alloc_fixed +#define qe_muram_free cpm_muram_free +#define qe_muram_addr cpm_muram_addr +#define qe_muram_offset cpm_muram_offset /* Structure that defines QE firmware binary files. * @@ -199,20 +193,6 @@ struct qe_bd { #define BD_STATUS_MASK 0xffff0000 #define BD_LENGTH_MASK 0x0000ffff -#define BD_SC_EMPTY 0x8000 /* Receive is empty */ -#define BD_SC_READY 0x8000 /* Transmit is ready */ -#define BD_SC_WRAP 0x2000 /* Last buffer descriptor */ -#define BD_SC_INTRPT 0x1000 /* Interrupt on change */ -#define BD_SC_LAST 0x0800 /* Last buffer in frame */ -#define BD_SC_CM 0x0200 /* Continous mode */ -#define BD_SC_ID 0x0100 /* Rec'd too many idles */ -#define BD_SC_P 0x0100 /* xmt preamble */ -#define BD_SC_BR 0x0020 /* Break received */ -#define BD_SC_FR 0x0010 /* Framing error */ -#define BD_SC_PR 0x0008 /* Parity error */ -#define BD_SC_OV 0x0002 /* Overrun */ -#define BD_SC_CD 0x0001 /* ?? */ - /* Alignment */ #define QE_INTR_TABLE_ALIGN 16 /* ??? */ #define QE_ALIGNMENT_OF_BD 8 -- cgit v1.2.3 From 995ada8d5e6b3d5a32ca3e544a564d0623c4f3fa Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 6 Jun 2008 00:22:29 +1000 Subject: powerpc/4xx: PCIe driver now detects if a port is disabled via the dev-tree This patch add a check to the PPC4xx PCIe driver to detect if the port is disabled via the device-tree. This is needed for the AMCC Canyonlands board which has an option to either select 2 PCIe ports or 1 PCIe port and one SATA port. The SATA port and the 1st PCIe port pins are multiplexed so we can't start both drivers. Signed-off-by: Stefan Roese Acked-by: Benjamin Herrenschmidt Signed-off-by: Josh Boyer --- arch/powerpc/sysdev/ppc4xx_pci.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index b4a54c52e880..76886cf0e6dc 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c @@ -1634,6 +1634,15 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np) } port = &ppc4xx_pciex_ports[portno]; port->index = portno; + + /* + * Check if device is enabled + */ + if (!of_device_is_available(np)) { + printk(KERN_INFO "PCIE%d: Port disabled via device-tree\n", port->index); + return; + } + port->node = of_node_get(np); pval = of_get_property(np, "sdr-base", NULL); if (pval == NULL) { -- cgit v1.2.3 From 5848f16947026601b9cb4df694bb9f44dfefc354 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 11 Jun 2008 16:32:48 +0400 Subject: powerpc/QE: qe_reset should be __init This patch fixes following section mismatch: WARNING: arch/powerpc/sysdev/built-in.o(.text+0x11d8): Section mismatch in reference from the function qe_reset() to the function .init.text:cpm_muram_init() Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/qe_lib/qe.c | 2 +- include/asm-powerpc/qe.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 28e05df952de..9e82d7e725a5 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -87,7 +87,7 @@ phys_addr_t get_qe_base(void) EXPORT_SYMBOL(get_qe_base); -void qe_reset(void) +void __init qe_reset(void) { if (qe_immr == NULL) qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE); diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h index 80807fd6a706..1355e7267013 100644 --- a/include/asm-powerpc/qe.h +++ b/include/asm-powerpc/qe.h @@ -84,7 +84,7 @@ static inline bool qe_clock_is_brg(enum qe_clock clk) extern spinlock_t cmxgcr_lock; /* Export QE common operations */ -extern void qe_reset(void); +extern void __init qe_reset(void); /* QE PIO */ #define QE_PIO_PINS 32 -- cgit v1.2.3 From 5ce4b59653b2c2053cd9a011918ac1e4747f24cc Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 17 Jun 2008 19:01:38 -0400 Subject: powerpc/4xx: Workaround for PPC440EPx/GRx PCI_28 Errata The 440EPx/GRx chips don't support PCI MRM commands. Drivers determine this by looking for a zero value in the PCI cache line size register. However, some drivers write to this register upon initialization. This can cause MRMs to be used on these chips, which may cause deadlocks on PLB4. The workaround implemented here introduces a new indirect_type flag, called PPC_INDIRECT_TYPE_BROKEN_MRM. This is set in the pci_controller structure in the pci fixup function for 4xx PCI bridges by determining if the bridge is compatible with 440EPx/GRx. The flag is checked in the indirect_write_config function, and forces any writes to the PCI_CACHE_LINE_SIZE register to be zero, which will disable MRMs for these chips. A similar workaround has been tested by AMCC on various PCI cards, such as the Silicon Image ATA card and Intel E1000 GIGE card. Hangs were seen with the Silicon Image card, and MRMs were seen on the bus with a PCI analyzer. With the workaround in place, the card functioned properly and only Memory Reads were seen on the bus with the analyzer. Acked-by: Stefan Roese Signed-off-by: Josh Boyer --- arch/powerpc/sysdev/indirect_pci.c | 6 ++++++ arch/powerpc/sysdev/ppc4xx_pci.c | 5 +++++ include/asm-powerpc/pci-bridge.h | 3 +++ 3 files changed, 14 insertions(+) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c index cfbd2aae93e8..7fd49c97501a 100644 --- a/arch/powerpc/sysdev/indirect_pci.c +++ b/arch/powerpc/sysdev/indirect_pci.c @@ -123,6 +123,12 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset, (bus->number == hose->first_busno)) val &= 0xffffff00; + /* Workaround for PCI_28 Errata in 440EPx/GRx */ + if ((hose->indirect_type & PPC_INDIRECT_TYPE_BROKEN_MRM) && + offset == PCI_CACHE_LINE_SIZE) { + val = 0; + } + /* * Note: the caller has already checked that offset is * suitably aligned and that len is 1, 2 or 4. diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 76886cf0e6dc..fb368dfde5d4 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c @@ -75,6 +75,11 @@ static void fixup_ppc4xx_pci_bridge(struct pci_dev *dev) !of_device_is_compatible(hose->dn, "ibm,plb-pci")) return; + if (of_device_is_compatible(hose->dn, "ibm,plb440epx-pci") || + of_device_is_compatible(hose->dn, "ibm,plb440grx-pci")) { + hose->indirect_type |= PPC_INDIRECT_TYPE_BROKEN_MRM; + } + /* Hide the PCI host BARs from the kernel as their content doesn't * fit well in the resource management */ diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h index b95d033ae6e6..ae2ea803a0f2 100644 --- a/include/asm-powerpc/pci-bridge.h +++ b/include/asm-powerpc/pci-bridge.h @@ -92,12 +92,15 @@ struct pci_controller { * anything but the PHB. Only allow talking to the PHB if this is * set. * BIG_ENDIAN - cfg_addr is a big endian register + * BROKEN_MRM - the 440EPx/GRx chips have an errata that causes hangs on + * the PLB4. Effectively disable MRM commands by setting this. */ #define PPC_INDIRECT_TYPE_SET_CFG_TYPE 0x00000001 #define PPC_INDIRECT_TYPE_EXT_REG 0x00000002 #define PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x00000004 #define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008 #define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010 +#define PPC_INDIRECT_TYPE_BROKEN_MRM 0x00000020 u32 indirect_type; #endif /* !CONFIG_PPC64 */ /* Currently, we limit ourselves to 1 IO range and 3 mem -- cgit v1.2.3 From d14b3dd6190af7ce4f88be68f8df828af6d44584 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 12 Jun 2008 03:42:14 +0400 Subject: powerpc/QE: use arch_initcall to probe QUICC Engine GPIOs It was discussed that global arch_initcall() is preferred way to probe QE GPIOs, so let's use it. Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/qe_lib/gpio.c | 5 ++++- include/asm-powerpc/qe.h | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c index c712e245dc4c..8e5a0bc36d0b 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/arch/powerpc/sysdev/qe_lib/gpio.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include @@ -102,7 +103,7 @@ static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) return 0; } -void __init qe_add_gpiochips(void) +static int __init qe_add_gpiochips(void) { struct device_node *np; @@ -143,4 +144,6 @@ err: kfree(qe_gc); /* try others anyway */ } + return 0; } +arch_initcall(qe_add_gpiochips); diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h index 1355e7267013..edee15d269ea 100644 --- a/include/asm-powerpc/qe.h +++ b/include/asm-powerpc/qe.h @@ -101,7 +101,6 @@ struct qe_pio_regs { #endif }; -extern void __init qe_add_gpiochips(void); extern int par_io_init(struct device_node *np); extern int par_io_of_config(struct device_node *np); #define QE_PIO_DIR_IN 2 -- cgit v1.2.3 From b7d7a2404f80386307ccc0cde63d8d2a5e3bc85c Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 26 Jun 2008 11:22:13 +0200 Subject: powerpc: convert to generic helpers for IPI function calls This converts ppc to use the new helpers for smp_call_function() and friends, and adds support for smp_call_function_single(). ppc loses the timeout functionality of smp_call_function_mask() with this change, as the generic code does not provide that. Acked-by: Paul Mackerras Signed-off-by: Jens Axboe --- arch/powerpc/Kconfig | 1 + arch/powerpc/kernel/smp.c | 234 +++----------------------------- arch/powerpc/platforms/cell/interrupt.c | 1 + arch/powerpc/platforms/ps3/smp.c | 7 +- arch/powerpc/platforms/pseries/xics.c | 6 +- arch/powerpc/sysdev/mpic.c | 2 +- include/asm-powerpc/smp.h | 8 +- 7 files changed, 33 insertions(+), 226 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 3934e2659407..852d40c29637 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -110,6 +110,7 @@ config PPC select HAVE_KPROBES select HAVE_KRETPROBES select HAVE_LMB + select USE_GENERIC_SMP_HELPERS if SMP config EARLY_PRINTK bool diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 1457aa0a08f1..37a5ab410dcc 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -72,12 +72,8 @@ struct smp_ops_t *smp_ops; static volatile unsigned int cpu_callin_map[NR_CPUS]; -void smp_call_function_interrupt(void); - int smt_enabled_at_boot = 1; -static int ipi_fail_ok; - static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL; #ifdef CONFIG_PPC64 @@ -99,12 +95,15 @@ void smp_message_recv(int msg) { switch(msg) { case PPC_MSG_CALL_FUNCTION: - smp_call_function_interrupt(); + generic_smp_call_function_interrupt(); break; case PPC_MSG_RESCHEDULE: /* XXX Do we have to do this? */ set_need_resched(); break; + case PPC_MSG_CALL_FUNC_SINGLE: + generic_smp_call_function_single_interrupt(); + break; case PPC_MSG_DEBUGGER_BREAK: if (crash_ipi_function_ptr) { crash_ipi_function_ptr(get_irq_regs()); @@ -128,6 +127,19 @@ void smp_send_reschedule(int cpu) smp_ops->message_pass(cpu, PPC_MSG_RESCHEDULE); } +void arch_send_call_function_single_ipi(int cpu) +{ + smp_ops->message_pass(cpu, PPC_MSG_CALL_FUNC_SINGLE); +} + +void arch_send_call_function_ipi(cpumask_t mask) +{ + unsigned int cpu; + + for_each_cpu_mask(cpu, mask) + smp_ops->message_pass(cpu, PPC_MSG_CALL_FUNCTION); +} + #ifdef CONFIG_DEBUGGER void smp_send_debugger_break(int cpu) { @@ -154,215 +166,9 @@ static void stop_this_cpu(void *dummy) ; } -/* - * Structure and data for smp_call_function(). This is designed to minimise - * static memory requirements. It also looks cleaner. - * Stolen from the i386 version. - */ -static __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_lock); - -static struct call_data_struct { - void (*func) (void *info); - void *info; - atomic_t started; - atomic_t finished; - int wait; -} *call_data; - -/* delay of at least 8 seconds */ -#define SMP_CALL_TIMEOUT 8 - -/* - * These functions send a 'generic call function' IPI to other online - * CPUS in the system. - * - * [SUMMARY] Run a function on other CPUs. - * The function to run. This must be fast and non-blocking. - * An arbitrary pointer to pass to the function. - * currently unused. - * If true, wait (atomically) until function has completed on other CPUs. - * [RETURNS] 0 on success, else a negative status code. Does not return until - * remote CPUs are nearly ready to execute <> or are or have executed. - * is a cpu map of the cpus to send IPI to. - * - * You must not call this function with disabled interrupts or from a - * hardware interrupt handler or from a bottom half handler. - */ -static int __smp_call_function_map(void (*func) (void *info), void *info, - int nonatomic, int wait, cpumask_t map) -{ - struct call_data_struct data; - int ret = -1, num_cpus; - int cpu; - u64 timeout; - - if (unlikely(smp_ops == NULL)) - return ret; - - data.func = func; - data.info = info; - atomic_set(&data.started, 0); - data.wait = wait; - if (wait) - atomic_set(&data.finished, 0); - - /* remove 'self' from the map */ - if (cpu_isset(smp_processor_id(), map)) - cpu_clear(smp_processor_id(), map); - - /* sanity check the map, remove any non-online processors. */ - cpus_and(map, map, cpu_online_map); - - num_cpus = cpus_weight(map); - if (!num_cpus) - goto done; - - call_data = &data; - smp_wmb(); - /* Send a message to all CPUs in the map */ - for_each_cpu_mask(cpu, map) - smp_ops->message_pass(cpu, PPC_MSG_CALL_FUNCTION); - - timeout = get_tb() + (u64) SMP_CALL_TIMEOUT * tb_ticks_per_sec; - - /* Wait for indication that they have received the message */ - while (atomic_read(&data.started) != num_cpus) { - HMT_low(); - if (get_tb() >= timeout) { - printk("smp_call_function on cpu %d: other cpus not " - "responding (%d)\n", smp_processor_id(), - atomic_read(&data.started)); - if (!ipi_fail_ok) - debugger(NULL); - goto out; - } - } - - /* optionally wait for the CPUs to complete */ - if (wait) { - while (atomic_read(&data.finished) != num_cpus) { - HMT_low(); - if (get_tb() >= timeout) { - printk("smp_call_function on cpu %d: other " - "cpus not finishing (%d/%d)\n", - smp_processor_id(), - atomic_read(&data.finished), - atomic_read(&data.started)); - debugger(NULL); - goto out; - } - } - } - - done: - ret = 0; - - out: - call_data = NULL; - HMT_medium(); - return ret; -} - -static int __smp_call_function(void (*func)(void *info), void *info, - int nonatomic, int wait) -{ - int ret; - spin_lock(&call_lock); - ret =__smp_call_function_map(func, info, nonatomic, wait, - cpu_online_map); - spin_unlock(&call_lock); - return ret; -} - -int smp_call_function(void (*func) (void *info), void *info, int nonatomic, - int wait) -{ - /* Can deadlock when called with interrupts disabled */ - WARN_ON(irqs_disabled()); - - return __smp_call_function(func, info, nonatomic, wait); -} -EXPORT_SYMBOL(smp_call_function); - -int smp_call_function_single(int cpu, void (*func) (void *info), void *info, - int nonatomic, int wait) -{ - cpumask_t map = CPU_MASK_NONE; - int ret = 0; - - /* Can deadlock when called with interrupts disabled */ - WARN_ON(irqs_disabled()); - - if (!cpu_online(cpu)) - return -EINVAL; - - cpu_set(cpu, map); - if (cpu != get_cpu()) { - spin_lock(&call_lock); - ret = __smp_call_function_map(func, info, nonatomic, wait, map); - spin_unlock(&call_lock); - } else { - local_irq_disable(); - func(info); - local_irq_enable(); - } - put_cpu(); - return ret; -} -EXPORT_SYMBOL(smp_call_function_single); - void smp_send_stop(void) { - int nolock; - - /* It's OK to fail sending the IPI, since the alternative is to - * be stuck forever waiting on the other CPU to take the interrupt. - * - * It's better to at least continue and go through reboot, since this - * function is usually called at panic or reboot time in the first - * place. - */ - ipi_fail_ok = 1; - - /* Don't deadlock in case we got called through panic */ - nolock = !spin_trylock(&call_lock); - __smp_call_function_map(stop_this_cpu, NULL, 1, 0, cpu_online_map); - if (!nolock) - spin_unlock(&call_lock); -} - -void smp_call_function_interrupt(void) -{ - void (*func) (void *info); - void *info; - int wait; - - /* call_data will be NULL if the sender timed out while - * waiting on us to receive the call. - */ - if (!call_data) - return; - - func = call_data->func; - info = call_data->info; - wait = call_data->wait; - - if (!wait) - smp_mb__before_atomic_inc(); - - /* - * Notify initiating CPU that I've grabbed the data and am - * about to execute the function - */ - atomic_inc(&call_data->started); - /* - * At this point the info structure may be out of scope unless wait==1 - */ - (*func)(info); - if (wait) { - smp_mb__before_atomic_inc(); - atomic_inc(&call_data->finished); - } + smp_call_function(stop_this_cpu, NULL, 0, 0); } extern struct gettimeofday_struct do_gtod; @@ -596,9 +402,9 @@ int __devinit start_secondary(void *unused) secondary_cpu_time_init(); - spin_lock(&call_lock); + ipi_call_lock(); cpu_set(cpu, cpu_online_map); - spin_unlock(&call_lock); + ipi_call_unlock(); local_irq_enable(); diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 5bf7df146022..2d5bb22d6c09 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -218,6 +218,7 @@ void iic_request_IPIs(void) { iic_request_ipi(PPC_MSG_CALL_FUNCTION, "IPI-call"); iic_request_ipi(PPC_MSG_RESCHEDULE, "IPI-resched"); + iic_request_ipi(PPC_MSG_CALL_FUNC_SINGLE, "IPI-call-single"); #ifdef CONFIG_DEBUGGER iic_request_ipi(PPC_MSG_DEBUGGER_BREAK, "IPI-debug"); #endif /* CONFIG_DEBUGGER */ diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c index f0b12f212363..a0927a3bacb7 100644 --- a/arch/powerpc/platforms/ps3/smp.c +++ b/arch/powerpc/platforms/ps3/smp.c @@ -105,9 +105,10 @@ static void __init ps3_smp_setup_cpu(int cpu) * to index needs to be setup. */ - BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION != 0); - BUILD_BUG_ON(PPC_MSG_RESCHEDULE != 1); - BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3); + BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION != 0); + BUILD_BUG_ON(PPC_MSG_RESCHEDULE != 1); + BUILD_BUG_ON(PPC_MSG_CALL_FUNC_SINGLE != 2); + BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3); for (i = 0; i < MSG_COUNT; i++) { result = ps3_event_receive_port_setup(cpu, &virqs[i]); diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index ebebc28fe895..0fc830f576f5 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -383,13 +383,11 @@ static irqreturn_t xics_ipi_dispatch(int cpu) mb(); smp_message_recv(PPC_MSG_RESCHEDULE); } -#if 0 - if (test_and_clear_bit(PPC_MSG_MIGRATE_TASK, + if (test_and_clear_bit(PPC_MSG_CALL_FUNC_SINGLE, &xics_ipi_message[cpu].value)) { mb(); - smp_message_recv(PPC_MSG_MIGRATE_TASK); + smp_message_recv(PPC_MSG_CALL_FUNC_SINGLE); } -#endif #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, &xics_ipi_message[cpu].value)) { diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 7680001676a6..6c90c95b454e 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1494,7 +1494,7 @@ void mpic_request_ipis(void) static char *ipi_names[] = { "IPI0 (call function)", "IPI1 (reschedule)", - "IPI2 (unused)", + "IPI2 (call function single)", "IPI3 (debugger break)", }; BUG_ON(mpic == NULL); diff --git a/include/asm-powerpc/smp.h b/include/asm-powerpc/smp.h index 505f35bacaa9..c663a1fa77c5 100644 --- a/include/asm-powerpc/smp.h +++ b/include/asm-powerpc/smp.h @@ -67,10 +67,7 @@ DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); * in /proc/interrupts will be wrong!!! --Troy */ #define PPC_MSG_CALL_FUNCTION 0 #define PPC_MSG_RESCHEDULE 1 -/* This is unused now */ -#if 0 -#define PPC_MSG_MIGRATE_TASK 2 -#endif +#define PPC_MSG_CALL_FUNC_SINGLE 2 #define PPC_MSG_DEBUGGER_BREAK 3 void smp_init_iSeries(void); @@ -117,6 +114,9 @@ extern void smp_generic_take_timebase(void); extern struct smp_ops_t *smp_ops; +extern void arch_send_call_function_single_ipi(int cpu); +extern void arch_send_call_function_ipi(cpumask_t mask); + #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ -- cgit v1.2.3 From 0d1cde235874b00905bce23f659690d060ebf475 Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Mon, 30 Jun 2008 19:01:26 -0400 Subject: powerpc/i2c: Convert i2c-mpc into an of_platform driver Convert i2c-mpc to an of_platform driver. Utilize the code in drivers/of-i2c.c to make i2c modules dynamically loadable by the device tree. Signed-off-by: Jon Smirl Signed-off-by: Grant Likely --- arch/powerpc/sysdev/fsl_soc.c | 133 ------------------------------------------ drivers/i2c/busses/i2c-mpc.c | 104 +++++++++++++++++++-------------- 2 files changed, 60 insertions(+), 177 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index ca54563d5c7e..ebcec7362f95 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -414,139 +414,6 @@ err: arch_initcall(gfar_of_init); -#ifdef CONFIG_I2C_BOARDINFO -#include -struct i2c_driver_device { - char *of_device; - char *i2c_type; -}; - -static struct i2c_driver_device i2c_devices[] __initdata = { - {"ricoh,rs5c372a", "rs5c372a"}, - {"ricoh,rs5c372b", "rs5c372b"}, - {"ricoh,rv5c386", "rv5c386"}, - {"ricoh,rv5c387a", "rv5c387a"}, - {"dallas,ds1307", "ds1307"}, - {"dallas,ds1337", "ds1337"}, - {"dallas,ds1338", "ds1338"}, - {"dallas,ds1339", "ds1339"}, - {"dallas,ds1340", "ds1340"}, - {"stm,m41t00", "m41t00"}, - {"dallas,ds1374", "ds1374"}, - {"cirrus,cs4270", "cs4270"}, -}; - -static int __init of_find_i2c_driver(struct device_node *node, - struct i2c_board_info *info) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) { - if (!of_device_is_compatible(node, i2c_devices[i].of_device)) - continue; - if (strlcpy(info->type, i2c_devices[i].i2c_type, - I2C_NAME_SIZE) >= I2C_NAME_SIZE) - return -ENOMEM; - return 0; - } - - pr_warning("fsl_soc.c: unrecognized i2c node %s\n", - (const char *) of_get_property(node, "compatible", NULL)); - - return -ENODEV; -} - -static void __init of_register_i2c_devices(struct device_node *adap_node, - int bus_num) -{ - struct device_node *node = NULL; - - while ((node = of_get_next_child(adap_node, node))) { - struct i2c_board_info info = {}; - const u32 *addr; - int len; - - addr = of_get_property(node, "reg", &len); - if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) { - printk(KERN_WARNING "fsl_soc.c: invalid i2c device entry\n"); - continue; - } - - info.irq = irq_of_parse_and_map(node, 0); - if (info.irq == NO_IRQ) - info.irq = -1; - - if (of_find_i2c_driver(node, &info) < 0) - continue; - - info.addr = *addr; - - i2c_register_board_info(bus_num, &info, 1); - } -} - -static int __init fsl_i2c_of_init(void) -{ - struct device_node *np; - unsigned int i = 0; - struct platform_device *i2c_dev; - int ret; - - for_each_compatible_node(np, NULL, "fsl-i2c") { - struct resource r[2]; - struct fsl_i2c_platform_data i2c_data; - const unsigned char *flags = NULL; - int idx; - const u32 *iprop; - - memset(&r, 0, sizeof(r)); - memset(&i2c_data, 0, sizeof(i2c_data)); - - ret = of_address_to_resource(np, 0, &r[0]); - if (ret) - goto err; - - of_irq_to_resource(np, 0, &r[1]); - - iprop = of_get_property(np, "cell-index", NULL); - idx = iprop ? *iprop : i; - - i2c_dev = platform_device_register_simple("fsl-i2c", idx, r, 2); - if (IS_ERR(i2c_dev)) { - ret = PTR_ERR(i2c_dev); - goto err; - } - - i2c_data.device_flags = 0; - flags = of_get_property(np, "dfsrr", NULL); - if (flags) - i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR; - - flags = of_get_property(np, "fsl5200-clocking", NULL); - if (flags) - i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200; - - ret = - platform_device_add_data(i2c_dev, &i2c_data, - sizeof(struct - fsl_i2c_platform_data)); - if (ret) - goto unreg; - - of_register_i2c_devices(np, idx); - i++; - } - - return 0; - -unreg: - platform_device_unregister(i2c_dev); -err: - return ret; -} - -arch_initcall(fsl_i2c_of_init); -#endif #ifdef CONFIG_PPC_83xx static int __init mpc83xx_wdt_init(void) diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index a076129de7e8..4fdfb62d6f38 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include @@ -25,13 +26,13 @@ #include #include -#define MPC_I2C_ADDR 0x00 +#define DRV_NAME "mpc-i2c" + #define MPC_I2C_FDR 0x04 #define MPC_I2C_CR 0x08 #define MPC_I2C_SR 0x0c #define MPC_I2C_DR 0x10 #define MPC_I2C_DFSRR 0x14 -#define MPC_I2C_REGION 0x20 #define CCR_MEN 0x80 #define CCR_MIEN 0x40 @@ -315,102 +316,117 @@ static struct i2c_adapter mpc_ops = { .timeout = 1, }; -static int fsl_i2c_probe(struct platform_device *pdev) +static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_id *match) { int result = 0; struct mpc_i2c *i2c; - struct fsl_i2c_platform_data *pdata; - struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data; i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); if (!i2c) return -ENOMEM; - i2c->irq = platform_get_irq(pdev, 0); - if (i2c->irq < 0) - i2c->irq = NO_IRQ; /* Use polling */ + if (of_get_property(op->node, "dfsrr", NULL)) + i2c->flags |= FSL_I2C_DEV_SEPARATE_DFSRR; - i2c->flags = pdata->device_flags; - init_waitqueue_head(&i2c->queue); + if (of_device_is_compatible(op->node, "fsl,mpc5200-i2c") || + of_device_is_compatible(op->node, "mpc5200-i2c")) + i2c->flags |= FSL_I2C_DEV_CLOCK_5200; - i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION); + init_waitqueue_head(&i2c->queue); + i2c->base = of_iomap(op->node, 0); if (!i2c->base) { printk(KERN_ERR "i2c-mpc - failed to map controller\n"); result = -ENOMEM; goto fail_map; } - if (i2c->irq != NO_IRQ) - if ((result = request_irq(i2c->irq, mpc_i2c_isr, - IRQF_SHARED, "i2c-mpc", i2c)) < 0) { - printk(KERN_ERR - "i2c-mpc - failed to attach interrupt\n"); - goto fail_irq; + i2c->irq = irq_of_parse_and_map(op->node, 0); + if (i2c->irq != NO_IRQ) { /* i2c->irq = NO_IRQ implies polling */ + result = request_irq(i2c->irq, mpc_i2c_isr, + IRQF_SHARED, "i2c-mpc", i2c); + if (result < 0) { + printk(KERN_ERR "i2c-mpc - failed to attach interrupt\n"); + goto fail_request; } - + } + mpc_i2c_setclock(i2c); - platform_set_drvdata(pdev, i2c); + + dev_set_drvdata(&op->dev, i2c); i2c->adap = mpc_ops; - i2c->adap.nr = pdev->id; i2c_set_adapdata(&i2c->adap, i2c); - i2c->adap.dev.parent = &pdev->dev; - if ((result = i2c_add_numbered_adapter(&i2c->adap)) < 0) { + i2c->adap.dev.parent = &op->dev; + + result = i2c_add_adapter(&i2c->adap); + if (result < 0) { printk(KERN_ERR "i2c-mpc - failed to add adapter\n"); goto fail_add; } + of_register_i2c_devices(&i2c->adap, op->node); return result; - fail_add: - if (i2c->irq != NO_IRQ) - free_irq(i2c->irq, i2c); - fail_irq: - iounmap(i2c->base); - fail_map: + fail_add: + dev_set_drvdata(&op->dev, NULL); + free_irq(i2c->irq, i2c); + fail_request: + irq_dispose_mapping(i2c->irq); + iounmap(i2c->base); + fail_map: kfree(i2c); return result; }; -static int fsl_i2c_remove(struct platform_device *pdev) +static int __devexit fsl_i2c_remove(struct of_device *op) { - struct mpc_i2c *i2c = platform_get_drvdata(pdev); + struct mpc_i2c *i2c = dev_get_drvdata(&op->dev); i2c_del_adapter(&i2c->adap); - platform_set_drvdata(pdev, NULL); + dev_set_drvdata(&op->dev, NULL); if (i2c->irq != NO_IRQ) free_irq(i2c->irq, i2c); + irq_dispose_mapping(i2c->irq); iounmap(i2c->base); kfree(i2c); return 0; }; -/* work with hotplug and coldplug */ -MODULE_ALIAS("platform:fsl-i2c"); +static const struct of_device_id mpc_i2c_of_match[] = { + {.compatible = "fsl-i2c",}, + {}, +}; +MODULE_DEVICE_TABLE(of, mpc_i2c_of_match); + /* Structure for a device driver */ -static struct platform_driver fsl_i2c_driver = { - .probe = fsl_i2c_probe, - .remove = fsl_i2c_remove, - .driver = { - .owner = THIS_MODULE, - .name = "fsl-i2c", +static struct of_platform_driver mpc_i2c_driver = { + .match_table = mpc_i2c_of_match, + .probe = fsl_i2c_probe, + .remove = __devexit_p(fsl_i2c_remove), + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, }, }; static int __init fsl_i2c_init(void) { - return platform_driver_register(&fsl_i2c_driver); + int rv; + + rv = of_register_platform_driver(&mpc_i2c_driver); + if (rv) + printk(KERN_ERR DRV_NAME + " of_register_platform_driver failed (%i)\n", rv); + return rv; } static void __exit fsl_i2c_exit(void) { - platform_driver_unregister(&fsl_i2c_driver); + of_unregister_platform_driver(&mpc_i2c_driver); } module_init(fsl_i2c_init); -- cgit v1.2.3 From 7ba6d6dc8d58c49cff0533819195b44fb35d6ece Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 1 Jul 2008 21:38:16 -0600 Subject: powerpc/mpc5200: Add PSC helpers for bestcomm engine Simplify the interface for setting up bestcomm DMA to PSCs by adding some helper functions. The helper function sets the correct values for the initator and ipr values in PSC DMA tasks based on the PSC number. Signed-off-by: Grant Likely --- arch/powerpc/sysdev/bestcomm/gen_bd.c | 95 +++++++++++++++++++++++++++++++++++ arch/powerpc/sysdev/bestcomm/gen_bd.h | 5 ++ 2 files changed, 100 insertions(+) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/bestcomm/gen_bd.c b/arch/powerpc/sysdev/bestcomm/gen_bd.c index 8d33eafbb3f4..a3a134c35b0a 100644 --- a/arch/powerpc/sysdev/bestcomm/gen_bd.c +++ b/arch/powerpc/sysdev/bestcomm/gen_bd.c @@ -20,6 +20,7 @@ #include #include +#include #include "bestcomm.h" #include "bestcomm_priv.h" @@ -253,6 +254,100 @@ bcom_gen_bd_tx_release(struct bcom_task *tsk) } EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_release); +/* --------------------------------------------------------------------- + * PSC support code + */ + +/** + * bcom_psc_parameters - Bestcomm initialization value table for PSC devices + * + * This structure is only used internally. It is a lookup table for PSC + * specific parameters to bestcomm tasks. + */ +static struct bcom_psc_params { + int rx_initiator; + int rx_ipr; + int tx_initiator; + int tx_ipr; +} bcom_psc_params[] = { + [0] = { + .rx_initiator = BCOM_INITIATOR_PSC1_RX, + .rx_ipr = BCOM_IPR_PSC1_RX, + .tx_initiator = BCOM_INITIATOR_PSC1_TX, + .tx_ipr = BCOM_IPR_PSC1_TX, + }, + [1] = { + .rx_initiator = BCOM_INITIATOR_PSC2_RX, + .rx_ipr = BCOM_IPR_PSC2_RX, + .tx_initiator = BCOM_INITIATOR_PSC2_TX, + .tx_ipr = BCOM_IPR_PSC2_TX, + }, + [2] = { + .rx_initiator = BCOM_INITIATOR_PSC3_RX, + .rx_ipr = BCOM_IPR_PSC3_RX, + .tx_initiator = BCOM_INITIATOR_PSC3_TX, + .tx_ipr = BCOM_IPR_PSC3_TX, + }, + [3] = { + .rx_initiator = BCOM_INITIATOR_PSC4_RX, + .rx_ipr = BCOM_IPR_PSC4_RX, + .tx_initiator = BCOM_INITIATOR_PSC4_TX, + .tx_ipr = BCOM_IPR_PSC4_TX, + }, + [4] = { + .rx_initiator = BCOM_INITIATOR_PSC5_RX, + .rx_ipr = BCOM_IPR_PSC5_RX, + .tx_initiator = BCOM_INITIATOR_PSC5_TX, + .tx_ipr = BCOM_IPR_PSC5_TX, + }, + [5] = { + .rx_initiator = BCOM_INITIATOR_PSC6_RX, + .rx_ipr = BCOM_IPR_PSC6_RX, + .tx_initiator = BCOM_INITIATOR_PSC6_TX, + .tx_ipr = BCOM_IPR_PSC6_TX, + }, +}; + +/** + * bcom_psc_gen_bd_rx_init - Allocate a receive bcom_task for a PSC port + * @psc_num: Number of the PSC to allocate a task for + * @queue_len: number of buffer descriptors to allocate for the task + * @fifo: physical address of FIFO register + * @maxbufsize: Maximum receive data size in bytes. + * + * Allocate a bestcomm task structure for receiving data from a PSC. + */ +struct bcom_task * bcom_psc_gen_bd_rx_init(unsigned psc_num, int queue_len, + phys_addr_t fifo, int maxbufsize) +{ + if (psc_num >= MPC52xx_PSC_MAXNUM) + return NULL; + + return bcom_gen_bd_rx_init(queue_len, fifo, + bcom_psc_params[psc_num].rx_initiator, + bcom_psc_params[psc_num].rx_ipr, + maxbufsize); +} +EXPORT_SYMBOL_GPL(bcom_psc_gen_bd_rx_init); + +/** + * bcom_psc_gen_bd_tx_init - Allocate a transmit bcom_task for a PSC port + * @psc_num: Number of the PSC to allocate a task for + * @queue_len: number of buffer descriptors to allocate for the task + * @fifo: physical address of FIFO register + * + * Allocate a bestcomm task structure for transmitting data to a PSC. + */ +struct bcom_task * +bcom_psc_gen_bd_tx_init(unsigned psc_num, int queue_len, phys_addr_t fifo) +{ + struct psc; + return bcom_gen_bd_tx_init(queue_len, fifo, + bcom_psc_params[psc_num].tx_initiator, + bcom_psc_params[psc_num].tx_ipr); +} +EXPORT_SYMBOL_GPL(bcom_psc_gen_bd_tx_init); + MODULE_DESCRIPTION("BestComm General Buffer Descriptor tasks driver"); MODULE_AUTHOR("Jeff Gibbons "); diff --git a/arch/powerpc/sysdev/bestcomm/gen_bd.h b/arch/powerpc/sysdev/bestcomm/gen_bd.h index 5b6fa803c6aa..de47260e69da 100644 --- a/arch/powerpc/sysdev/bestcomm/gen_bd.h +++ b/arch/powerpc/sysdev/bestcomm/gen_bd.h @@ -44,5 +44,10 @@ extern void bcom_gen_bd_tx_release(struct bcom_task *tsk); +/* PSC support utility wrappers */ +struct bcom_task * bcom_psc_gen_bd_rx_init(unsigned psc_num, int queue_len, + phys_addr_t fifo, int maxbufsize); +struct bcom_task * bcom_psc_gen_bd_tx_init(unsigned psc_num, int queue_len, + phys_addr_t fifo); #endif /* __BESTCOMM_GEN_BD_H__ */ -- cgit v1.2.3 From 08b6c06de5d3f37295f6dbf7010fb45ae5ee14a7 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 11 Jul 2008 16:17:58 -0600 Subject: powerpc/mpc5200: fix compile warnings in bestcomm driver Fix for the following compiler warnings: CC arch/powerpc/sysdev/bestcomm/bestcomm.o arch/powerpc/sysdev/bestcomm/bestcomm.c: In function 'mpc52xx_bcom_probe': arch/powerpc/sysdev/bestcomm/bestcomm.c:446: warning: format '%08lx' expects type 'long unsigned int', but argument 2 has type 'phys_addr_t' CC arch/powerpc/sysdev/bestcomm/sram.o arch/powerpc/sysdev/bestcomm/sram.c: In function 'bcom_sram_init': arch/powerpc/sysdev/bestcomm/sram.c:89: warning: format '%08lx' expects type 'long unsigned int', but argument 3 has type 'phys_addr_t' Signed-off-by: Grant Likely --- arch/powerpc/sysdev/bestcomm/bestcomm.c | 2 +- arch/powerpc/sysdev/bestcomm/sram.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index 64ec7d629363..446c9ea85b30 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c @@ -443,7 +443,7 @@ mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match) /* Done ! */ printk(KERN_INFO "DMA: MPC52xx BestComm engine @%08lx ok !\n", - bcom_eng->regs_base); + (long)bcom_eng->regs_base); return 0; diff --git a/arch/powerpc/sysdev/bestcomm/sram.c b/arch/powerpc/sysdev/bestcomm/sram.c index 99784383a843..5d74ef7a651f 100644 --- a/arch/powerpc/sysdev/bestcomm/sram.c +++ b/arch/powerpc/sysdev/bestcomm/sram.c @@ -86,7 +86,7 @@ int bcom_sram_init(struct device_node *sram_node, char *owner) if (!bcom_sram->base_virt) { printk(KERN_ERR "%s: bcom_sram_init: " "Map error SRAM zone 0x%08lx (0x%0x)!\n", - owner, bcom_sram->base_phys, bcom_sram->size ); + owner, (long)bcom_sram->base_phys, bcom_sram->size ); rv = -ENOMEM; goto error_release; } -- cgit v1.2.3 From 5e82eb333949e2f1652bf70d36dfaa875306ae11 Mon Sep 17 00:00:00 2001 From: Nye Liu Date: Fri, 27 Jun 2008 13:01:00 -0700 Subject: powerpc/CPM: Minor cosmetic changes to udbg_putc udbg_putc is a *function pointer* that is initialized during udbg_init_cpm. It might not be initialized properly when called from udbg_putc_cpm(), so (recursively) call udbg_putc_cpm() directly. Signed-off-by: Nye Liu Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/cpm_common.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 9b75d164bdf9..e4b7296acb2c 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c @@ -37,7 +37,7 @@ static void udbg_putc_cpm(char c) u8 __iomem *txbuf = (u8 __iomem __force *)in_be32(&cpm_udbg_txdesc[1]); if (c == '\n') - udbg_putc('\r'); + udbg_putc_cpm('\r'); while (in_be32(&cpm_udbg_txdesc[0]) & 0x80000000) ; @@ -53,7 +53,6 @@ void __init udbg_init_cpm(void) setbat(1, 0xf0000000, 0xf0000000, 1024*1024, _PAGE_IO); #endif udbg_putc = udbg_putc_cpm; - udbg_putc('X'); } } #endif -- cgit v1.2.3 From 2f3804edf971d2080243d2b4552bfd61ddfbf969 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 2 Jul 2008 01:36:15 -0500 Subject: powerpc/85xx: Add support for MPC8536DS Add support for the MPC8536 process and MPC8536DS reference board. The MPC8536 is an e500v2 based SoC which eTSEC, USB, SATA, PCI, and PCIe. The USB and SATA IP blocks are similiar to those on the PQ2 Pro SoCs and thus use the same drivers. Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8536ds.dts | 420 ++++++++ arch/powerpc/configs/mpc8536_ds_defconfig | 1637 +++++++++++++++++++++++++++++ arch/powerpc/platforms/85xx/Kconfig | 6 + arch/powerpc/platforms/85xx/Makefile | 1 + arch/powerpc/platforms/85xx/mpc8536_ds.c | 125 +++ arch/powerpc/sysdev/fsl_pci.c | 2 + include/linux/pci_ids.h | 2 + 7 files changed, 2193 insertions(+) create mode 100644 arch/powerpc/boot/dts/mpc8536ds.dts create mode 100644 arch/powerpc/configs/mpc8536_ds_defconfig create mode 100644 arch/powerpc/platforms/85xx/mpc8536_ds.c (limited to 'arch/powerpc/sysdev') diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts new file mode 100644 index 000000000000..98ad27a2ddee --- /dev/null +++ b/arch/powerpc/boot/dts/mpc8536ds.dts @@ -0,0 +1,420 @@ +/* + * MPC8536 DS Device Tree Source + * + * Copyright 2008 Freescale Semiconductor, Inc. + * + * 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. + */ + +/dts-v1/; + +/ { + model = "fsl,mpc8536ds"; + compatible = "fsl,mpc8536ds"; + #address-cells = <1>; + #size-cells = <1>; + + aliases { + ethernet0 = &enet0; + ethernet1 = &enet1; + serial0 = &serial0; + serial1 = &serial1; + pci0 = &pci0; + pci1 = &pci1; + pci2 = &pci2; + pci3 = &pci3; + }; + + cpus { + #cpus = <1>; + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,8536@0 { + device_type = "cpu"; + reg = <0>; + next-level-cache = <&L2>; + }; + }; + + memory { + device_type = "memory"; + reg = <00000000 00000000>; // Filled by U-Boot + }; + + soc@ffe00000 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "soc"; + ranges = <0x0 0xffe00000 0x100000>; + reg = <0xffe00000 0x1000>; + bus-frequency = <0>; // Filled out by uboot. + + memory-controller@2000 { + compatible = "fsl,mpc8536-memory-controller"; + reg = <0x2000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <18 0x2>; + }; + + L2: l2-cache-controller@20000 { + compatible = "fsl,mpc8536-l2-cache-controller"; + reg = <0x20000 0x1000>; + interrupt-parent = <&mpic>; + interrupts = <16 0x2>; + }; + + i2c@3000 { + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + compatible = "fsl-i2c"; + reg = <0x3000 0x100>; + interrupts = <43 0x2>; + interrupt-parent = <&mpic>; + dfsrr; + }; + + i2c@3100 { + #address-cells = <1>; + #size-cells = <0>; + cell-index = <1>; + compatible = "fsl-i2c"; + reg = <0x3100 0x100>; + interrupts = <43 0x2>; + interrupt-parent = <&mpic>; + dfsrr; + rtc@68 { + compatible = "dallas,ds3232"; + reg = <0x68>; + }; + }; + + dma@21300 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc8536-dma", "fsl,eloplus-dma"; + reg = <0x21300 4>; + ranges = <0 0x21100 0x200>; + cell-index = <0>; + dma-channel@0 { + compatible = "fsl,mpc8536-dma-channel", + "fsl,eloplus-dma-channel"; + reg = <0x0 0x80>; + cell-index = <0>; + interrupt-parent = <&mpic>; + interrupts = <14 0x2>; + }; + dma-channel@80 { + compatible = "fsl,mpc8536-dma-channel", + "fsl,eloplus-dma-channel"; + reg = <0x80 0x80>; + cell-index = <1>; + interrupt-parent = <&mpic>; + interrupts = <15 0x2>; + }; + dma-channel@100 { + compatible = "fsl,mpc8536-dma-channel", + "fsl,eloplus-dma-channel"; + reg = <0x100 0x80>; + cell-index = <2>; + interrupt-parent = <&mpic>; + interrupts = <16 0x2>; + }; + dma-channel@180 { + compatible = "fsl,mpc8536-dma-channel", + "fsl,eloplus-dma-channel"; + reg = <0x180 0x80>; + cell-index = <3>; + interrupt-parent = <&mpic>; + interrupts = <17 0x2>; + }; + }; + + mdio@24520 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,gianfar-mdio"; + reg = <0x24520 0x20>; + + phy0: ethernet-phy@0 { + interrupt-parent = <&mpic>; + interrupts = <10 0x1>; + reg = <0>; + device_type = "ethernet-phy"; + }; + phy1: ethernet-phy@1 { + interrupt-parent = <&mpic>; + interrupts = <10 0x1>; + reg = <1>; + device_type = "ethernet-phy"; + }; + }; + + usb@22000 { + compatible = "fsl,mpc8536-usb2-mph", "fsl-usb2-mph"; + reg = <0x22000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&mpic>; + interrupts = <28 0x2>; + phy_type = "ulpi"; + }; + + usb@23000 { + compatible = "fsl,mpc8536-usb2-mph", "fsl-usb2-mph"; + reg = <0x23000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&mpic>; + interrupts = <46 0x2>; + phy_type = "ulpi"; + }; + + enet0: ethernet@24000 { + cell-index = <0>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <0x24000 0x1000>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <29 2 30 2 34 2>; + interrupt-parent = <&mpic>; + phy-handle = <&phy1>; + phy-connection-type = "rgmii-id"; + }; + + enet1: ethernet@26000 { + cell-index = <1>; + device_type = "network"; + model = "TSEC"; + compatible = "gianfar"; + reg = <0x26000 0x1000>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <31 2 32 2 33 2>; + interrupt-parent = <&mpic>; + phy-handle = <&phy0>; + phy-connection-type = "rgmii-id"; + }; + + usb@2b000 { + compatible = "fsl,mpc8536-usb2-dr", "fsl-usb2-dr"; + reg = <0x2b000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&mpic>; + interrupts = <60 0x2>; + dr_mode = "peripheral"; + phy_type = "ulpi"; + }; + + serial0: serial@4500 { + cell-index = <0>; + device_type = "serial"; + compatible = "ns16550"; + reg = <0x4500 0x100>; + clock-frequency = <0>; + interrupts = <42 0x2>; + interrupt-parent = <&mpic>; + }; + + serial1: serial@4600 { + cell-index = <1>; + device_type = "serial"; + compatible = "ns16550"; + reg = <0x4600 0x100>; + clock-frequency = <0>; + interrupts = <42 0x2>; + interrupt-parent = <&mpic>; + }; + + sata@18000 { + compatible = "fsl,mpc8536-sata", "fsl,pq-sata"; + reg = <0x18000 0x1000>; + cell-index = <1>; + interrupts = <74 0x2>; + interrupt-parent = <&mpic>; + }; + + sata@19000 { + compatible = "fsl,mpc8536-sata", "fsl,pq-sata"; + reg = <0x19000 0x1000>; + cell-index = <2>; + interrupts = <41 0x2>; + interrupt-parent = <&mpic>; + }; + + global-utilities@e0000 { //global utilities block + compatible = "fsl,mpc8548-guts"; + reg = <0xe0000 0x1000>; + fsl,has-rstcr; + }; + + mpic: pic@40000 { + clock-frequency = <0>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + reg = <0x40000 0x40000>; + compatible = "chrp,open-pic"; + device_type = "open-pic"; + big-endian; + }; + + msi@41600 { + compatible = "fsl,mpc8536-msi", "fsl,mpic-msi"; + reg = <0x41600 0x80>; + msi-available-ranges = <0 0x100>; + interrupts = < + 0xe0 0 + 0xe1 0 + 0xe2 0 + 0xe3 0 + 0xe4 0 + 0xe5 0 + 0xe6 0 + 0xe7 0>; + interrupt-parent = <&mpic>; + }; + }; + + pci0: pci@ffe08000 { + cell-index = <0>; + compatible = "fsl,mpc8540-pci"; + device_type = "pci"; + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; + interrupt-map = < + + /* IDSEL 0x11 J17 Slot 1 */ + 0x8800 0 0 1 &mpic 1 1 + 0x8800 0 0 2 &mpic 2 1 + 0x8800 0 0 3 &mpic 3 1 + 0x8800 0 0 4 &mpic 4 1>; + + interrupt-parent = <&mpic>; + interrupts = <24 0x2>; + bus-range = <0 0xff>; + ranges = <0x02000000 0 0x80000000 0x80000000 0 0x10000000 + 0x01000000 0 0x00000000 0xffc00000 0 0x00010000>; + clock-frequency = <66666666>; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <0xffe08000 0x1000>; + }; + + pci1: pcie@ffe09000 { + cell-index = <1>; + compatible = "fsl,mpc8548-pcie"; + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <0xffe09000 0x1000>; + bus-range = <0 0xff>; + ranges = <0x02000000 0 0x98000000 0x98000000 0 0x08000000 + 0x01000000 0 0x00000000 0xffc20000 0 0x00010000>; + clock-frequency = <33333333>; + interrupt-parent = <&mpic>; + interrupts = <25 0x2>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = < + /* IDSEL 0x0 */ + 0000 0 0 1 &mpic 4 1 + 0000 0 0 2 &mpic 5 1 + 0000 0 0 3 &mpic 6 1 + 0000 0 0 4 &mpic 7 1 + >; + pcie@0 { + reg = <0 0 0 0 0>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + ranges = <0x02000000 0 0x98000000 + 0x02000000 0 0x98000000 + 0 0x08000000 + + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00010000>; + }; + }; + + pci2: pcie@ffe0a000 { + cell-index = <2>; + compatible = "fsl,mpc8548-pcie"; + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <0xffe0a000 0x1000>; + bus-range = <0 0xff>; + ranges = <0x02000000 0 0x90000000 0x90000000 0 0x08000000 + 0x01000000 0 0x00000000 0xffc10000 0 0x00010000>; + clock-frequency = <33333333>; + interrupt-parent = <&mpic>; + interrupts = <26 0x2>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = < + /* IDSEL 0x0 */ + 0000 0 0 1 &mpic 0 1 + 0000 0 0 2 &mpic 1 1 + 0000 0 0 3 &mpic 2 1 + 0000 0 0 4 &mpic 3 1 + >; + pcie@0 { + reg = <0 0 0 0 0>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + ranges = <0x02000000 0 0x90000000 + 0x02000000 0 0x90000000 + 0 0x08000000 + + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00010000>; + }; + }; + + pci3: pcie@ffe0b000 { + cell-index = <3>; + compatible = "fsl,mpc8548-pcie"; + device_type = "pci"; + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + reg = <0xffe0b000 0x1000>; + bus-range = <0 0xff>; + ranges = <0x02000000 0 0xa0000000 0xa0000000 0 0x20000000 + 0x01000000 0 0x00000000 0xffc30000 0 0x00010000>; + clock-frequency = <33333333>; + interrupt-parent = <&mpic>; + interrupts = <27 0x2>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = < + /* IDSEL 0x0 */ + 0000 0 0 1 &mpic 8 1 + 0000 0 0 2 &mpic 9 1 + 0000 0 0 3 &mpic 10 1 + 0000 0 0 4 &mpic 11 1 + >; + + pcie@0 { + reg = <0 0 0 0 0>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + ranges = <0x02000000 0 0xa0000000 + 0x02000000 0 0xa0000000 + 0 0x20000000 + + 0x01000000 0 0x00000000 + 0x01000000 0 0x00000000 + 0 0x00100000>; + }; + }; +}; diff --git a/arch/powerpc/configs/mpc8536_ds_defconfig b/arch/powerpc/configs/mpc8536_ds_defconfig new file mode 100644 index 000000000000..f1e2931de5da --- /dev/null +++ b/arch/powerpc/configs/mpc8536_ds_defconfig @@ -0,0 +1,1637 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26-rc8 +# Wed Jul 2 01:34:26 2008 +# +# CONFIG_PPC64 is not set + +# +# Processor support +# +# CONFIG_6xx is not set +CONFIG_PPC_85xx=y +# CONFIG_PPC_8xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_E200 is not set +CONFIG_E500=y +# CONFIG_PPC_E500MC is not set +CONFIG_BOOKE=y +CONFIG_FSL_BOOKE=y +CONFIG_FSL_EMB_PERFMON=y +# CONFIG_PHYS_64BIT is not set +CONFIG_SPE=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_PPC32=y +CONFIG_WORD_SIZE=32 +CONFIG_PPC_MERGE=y +CONFIG_MMU=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set +CONFIG_IRQ_PER_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_OF=y +CONFIG_PPC_UDBG_16550=y +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +CONFIG_DEFAULT_UIMAGE=y +# CONFIG_PPC_DCR_NATIVE is not set +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +CONFIG_AUDIT=y +# CONFIG_AUDITSYSCALL is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y +# CONFIG_FAIR_GROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +# CONFIG_HAVE_DMA_ATTRS is not set +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_CLASSIC_RCU=y + +# +# Platform support +# +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set +CONFIG_MPC85xx=y +# CONFIG_MPC8540_ADS is not set +# CONFIG_MPC8560_ADS is not set +# CONFIG_MPC85xx_CDS is not set +# CONFIG_MPC85xx_MDS is not set +CONFIG_MPC8536_DS=y +# CONFIG_MPC85xx_DS is not set +# CONFIG_KSI8560 is not set +# CONFIG_STX_GP3 is not set +# CONFIG_TQM8540 is not set +# CONFIG_TQM8541 is not set +# CONFIG_TQM8548 is not set +# CONFIG_TQM8555 is not set +# CONFIG_TQM8560 is not set +# CONFIG_SBC8548 is not set +# CONFIG_SBC8560 is not set +# CONFIG_IPIC is not set +CONFIG_MPIC=y +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_CPM2 is not set +# CONFIG_FSL_ULI1575 is not set + +# +# Kernel options +# +CONFIG_HIGHMEM=y +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_MATH_EMULATION=y +# CONFIG_IOMMU_HELPER is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_PM is not set +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_ZONE_DMA=y +CONFIG_PPC_INDIRECT_PCI=y +CONFIG_FSL_SOC=y +CONFIG_FSL_PCI=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_SYSCALL=y +# CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HAS_RAPIDIO is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_PAGE_OFFSET=0xc0000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_PHYSICAL_START=0x00000000 +CONFIG_PHYSICAL_ALIGN=0x10000000 +CONFIG_TASK_SIZE=0xc0000000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=y +CONFIG_NET_IPGRE=y +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_ARPD=y +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +CONFIG_INET_TUNNEL=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +CONFIG_OF_DEVICE=y +CONFIG_OF_I2C=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +CONFIG_BLK_DEV_NBD=y +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=524288 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +CONFIG_SCSI_LOGGING=y +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_SATA_PMP=y +# CONFIG_SATA_AHCI is not set +CONFIG_SATA_SIL24=y +CONFIG_SATA_FSL=y +CONFIG_ATA_SFF=y +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +CONFIG_SATA_SIL=y +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD640_PCI is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_SCH is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# Enable only one of the two stacks, unless you know what you are doing +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +CONFIG_DUMMY=y +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +CONFIG_VITESSE_PHY=y +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_NET_PCI is not set +# CONFIG_B44 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_E1000E_ENABLED is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +CONFIG_SKGE=y +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKY2=y +# CONFIG_SKY2_DEBUG is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +CONFIG_GIANFAR=y +CONFIG_GFAR_NAPI=y +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NIU is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set +# CONFIG_SFC is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_OF_PLATFORM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_CHARDEV is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_MPC=y +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_TINY_USB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_PLATFORM is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +CONFIG_SENSORS_EEPROM=y +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_SPI is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_THERMAL=y +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +CONFIG_DVB_CORE=m +CONFIG_VIDEO_MEDIA=m + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_DVB_CAPTURE_DRIVERS=y + +# +# Supported SAA7146 based PCI Adapters +# +# CONFIG_TTPCI_EEPROM is not set +# CONFIG_DVB_BUDGET_CORE is not set + +# +# Supported USB Adapters +# +# CONFIG_DVB_USB is not set +# CONFIG_DVB_TTUSB_BUDGET is not set +# CONFIG_DVB_TTUSB_DEC is not set +# CONFIG_DVB_CINERGYT2 is not set + +# +# Supported FlexCopII (B2C2) Adapters +# +# CONFIG_DVB_B2C2_FLEXCOP is not set + +# +# Supported BT878 Adapters +# + +# +# Supported Pluto2 Adapters +# +# CONFIG_DVB_PLUTO2 is not set + +# +# Supported DVB Frontends +# + +# +# Customise DVB Frontends +# +# CONFIG_DVB_FE_CUSTOMISE is not set + +# +# DVB-S (satellite) frontends +# +# CONFIG_DVB_CX24110 is not set +# CONFIG_DVB_CX24123 is not set +# CONFIG_DVB_MT312 is not set +# CONFIG_DVB_S5H1420 is not set +# CONFIG_DVB_STV0299 is not set +# CONFIG_DVB_TDA8083 is not set +# CONFIG_DVB_TDA10086 is not set +# CONFIG_DVB_VES1X93 is not set +# CONFIG_DVB_TUNER_ITD1000 is not set +# CONFIG_DVB_TDA826X is not set +# CONFIG_DVB_TUA6100 is not set + +# +# DVB-T (terrestrial) frontends +# +# CONFIG_DVB_SP8870 is not set +# CONFIG_DVB_SP887X is not set +# CONFIG_DVB_CX22700 is not set +# CONFIG_DVB_CX22702 is not set +# CONFIG_DVB_L64781 is not set +# CONFIG_DVB_TDA1004X is not set +# CONFIG_DVB_NXT6000 is not set +# CONFIG_DVB_MT352 is not set +# CONFIG_DVB_ZL10353 is not set +# CONFIG_DVB_DIB3000MB is not set +# CONFIG_DVB_DIB3000MC is not set +# CONFIG_DVB_DIB7000M is not set +# CONFIG_DVB_DIB7000P is not set +# CONFIG_DVB_TDA10048 is not set + +# +# DVB-C (cable) frontends +# +# CONFIG_DVB_VES1820 is not set +# CONFIG_DVB_TDA10021 is not set +# CONFIG_DVB_TDA10023 is not set +# CONFIG_DVB_STV0297 is not set + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +# CONFIG_DVB_NXT200X is not set +# CONFIG_DVB_OR51211 is not set +# CONFIG_DVB_OR51132 is not set +# CONFIG_DVB_BCM3510 is not set +# CONFIG_DVB_LGDT330X is not set +# CONFIG_DVB_S5H1409 is not set +# CONFIG_DVB_AU8522 is not set +# CONFIG_DVB_S5H1411 is not set + +# +# Digital terrestrial only tuners/PLL +# +# CONFIG_DVB_PLL is not set +# CONFIG_DVB_TUNER_DIB0070 is not set + +# +# SEC control devices for DVB-S +# +# CONFIG_DVB_LNBP21 is not set +# CONFIG_DVB_ISL6405 is not set +# CONFIG_DVB_ISL6421 is not set +CONFIG_DAB=y +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=y +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_AC97_CODEC=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS300 is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AW2 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_OXYGEN is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5530 is not set +# CONFIG_SND_DARLA20 is not set +# CONFIG_SND_GINA20 is not set +# CONFIG_SND_LAYLA20 is not set +# CONFIG_SND_DARLA24 is not set +# CONFIG_SND_GINA24 is not set +# CONFIG_SND_LAYLA24 is not set +# CONFIG_SND_MONA is not set +# CONFIG_SND_MIA is not set +# CONFIG_SND_ECHO3G is not set +# CONFIG_SND_INDIGO is not set +# CONFIG_SND_INDIGOIO is not set +# CONFIG_SND_INDIGODJ is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_HIFIER is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +CONFIG_SND_INTEL8X0=y +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RIPTIDE is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VIRTUOSO is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_AC97_POWER_SAVE is not set + +# +# ALSA PowerMac devices +# + +# +# ALSA PowerPC devices +# + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_USX2Y is not set +# CONFIG_SND_USB_CAIAQ is not set + +# +# System on Chip audio support +# +# CONFIG_SND_SOC is not set + +# +# ALSA SoC audio for Freescale SOCs +# + +# +# SoC Audio for the Texas Instruments OMAP +# + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=y +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_EHCI_FSL=y +CONFIG_USB_EHCI_HCD_PPC_OF=y +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PPC_OF=y +CONFIG_USB_OHCI_HCD_PPC_OF_BE=y +CONFIG_USB_OHCI_HCD_PPC_OF_LE=y +CONFIG_USB_OHCI_HCD_PCI=y +CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y +CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_GADGET is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +# CONFIG_EDAC is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +# CONFIG_RTC_DRV_PPC is not set +CONFIG_DMADEVICES=y + +# +# DMA Devices +# +CONFIG_FSL_DMA=y +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +# CONFIG_NET_DMA is not set +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_AFFS_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BFS_FS=m +CONFIG_EFS_FS=m +CONFIG_CRAMFS=y +CONFIG_VXFS_FS=m +# CONFIG_MINIX_FS is not set +CONFIG_HPFS_FS=m +CONFIG_QNX4FS_FS=m +# CONFIG_ROMFS_FS is not set +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_V4 is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_BIND34 is not set +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_HAVE_LMB=y + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUGGER is not set +# CONFIG_CODE_PATCHING_SELFTEST is not set +# CONFIG_FTR_FIXUP_SELFTEST is not set +# CONFIG_IRQSTACKS is not set +# CONFIG_VIRQ_DEBUG is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_PPC_EARLY_DEBUG is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +CONFIG_CRYPTO_SHA1=m +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_PPC_CLOCK is not set +# CONFIG_VIRTUALIZATION is not set diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 9cb8e29987a3..cebea5cadbc1 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -38,6 +38,12 @@ config MPC85xx_MDS help This option enables support for the MPC85xx MDS board +config MPC8536_DS + bool "Freescale MPC8536 DS" + select DEFAULT_UIMAGE + help + This option enables support for the MPC8536 DS board + config MPC85xx_DS bool "Freescale MPC85xx DS" select PPC_I8259 diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 6cea185f62b2..cb3054e1001d 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o +obj-$(CONFIG_MPC8536_DS) += mpc8536_ds.o obj-$(CONFIG_MPC85xx_DS) += mpc85xx_ds.o obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o obj-$(CONFIG_STX_GP3) += stx_gp3.o diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c new file mode 100644 index 000000000000..71d7c038961f --- /dev/null +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c @@ -0,0 +1,125 @@ +/* + * MPC8536 DS Board Setup + * + * Copyright 2008 Freescale Semiconductor, Inc. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +void __init mpc8536_ds_pic_init(void) +{ + struct mpic *mpic; + struct resource r; + struct device_node *np; + + np = of_find_node_by_type(np, "open-pic"); + if (np == NULL) { + printk(KERN_ERR "Could not find open-pic node\n"); + return; + } + + if (of_address_to_resource(np, 0, &r)) { + printk(KERN_ERR "Failed to map mpic register space\n"); + of_node_put(np); + return; + } + + mpic = mpic_alloc(np, r.start, + MPIC_PRIMARY | MPIC_WANTS_RESET | + MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, + 0, 256, " OpenPIC "); + BUG_ON(mpic == NULL); + of_node_put(np); + + mpic_init(mpic); +} + +/* + * Setup the architecture + */ +static void __init mpc8536_ds_setup_arch(void) +{ +#ifdef CONFIG_PCI + struct device_node *np; +#endif + + if (ppc_md.progress) + ppc_md.progress("mpc8536_ds_setup_arch()", 0); + +#ifdef CONFIG_PCI + for_each_node_by_type(np, "pci") { + if (of_device_is_compatible(np, "fsl,mpc8540-pci") || + of_device_is_compatible(np, "fsl,mpc8548-pcie")) { + struct resource rsrc; + of_address_to_resource(np, 0, &rsrc); + if ((rsrc.start & 0xfffff) == 0x8000) + fsl_add_bridge(np, 1); + else + fsl_add_bridge(np, 0); + } + } + +#endif + + printk("MPC8536 DS board from Freescale Semiconductor\n"); +} + +static struct of_device_id __initdata mpc8536_ds_ids[] = { + { .type = "soc", }, + { .compatible = "soc", }, + {}, +}; + +static int __init mpc8536_ds_publish_devices(void) +{ + return of_platform_bus_probe(NULL, mpc8536_ds_ids, NULL); +} +machine_device_initcall(mpc8536_ds, mpc8536_ds_publish_devices); + +/* + * Called very early, device-tree isn't unflattened + */ +static int __init mpc8536_ds_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + return of_flat_dt_is_compatible(root, "fsl,mpc8536ds"); +} + +define_machine(mpc8536_ds) { + .name = "MPC8536 DS", + .probe = mpc8536_ds_probe, + .setup_arch = mpc8536_ds_setup_arch, + .init_IRQ = mpc8536_ds_pic_init, +#ifdef CONFIG_PCI + .pcibios_fixup_bus = fsl_pcibios_fixup_bus, +#endif + .get_irq = mpic_get_irq, + .restart = fsl_rstcr_restart, + .calibrate_decr = generic_calibrate_decr, + .progress = udbg_progress, +}; diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 489ca5a397b1..87b0aa13ab48 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -243,6 +243,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8536E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8536, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 65953822c9cb..1cf4084b51e8 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2171,6 +2171,8 @@ #define PCI_DEVICE_ID_MPC8544 0x0033 #define PCI_DEVICE_ID_MPC8572E 0x0040 #define PCI_DEVICE_ID_MPC8572 0x0041 +#define PCI_DEVICE_ID_MPC8536E 0x0050 +#define PCI_DEVICE_ID_MPC8536 0x0051 #define PCI_DEVICE_ID_MPC8641 0x7010 #define PCI_DEVICE_ID_MPC8641D 0x7011 #define PCI_DEVICE_ID_MPC8610 0x7018 -- cgit v1.2.3