* Re: RFC: top level compatibles for virtual platforms
From: Grant Likely @ 2011-07-09 2:42 UTC (permalink / raw)
To: Tabi Timur-B04825
Cc: Wood Scott-B07421, linuxppc-dev@ozlabs.org, Alexander Graf,
Gala Kumar-B11780
In-Reply-To: <CAOZdJXVp5LHqYEMoqpnKEkuWyuE6kwU+Z9VwUYLPcz-+h_gqfw@mail.gmail.com>
On Friday, July 8, 2011, Tabi Timur-B04825 <B04825@freescale.com> wrote:
> On Fri, Jul 8, 2011 at 1:43 PM, Yoder Stuart-B08248
> <B08248@freescale.com> wrote:
>
>> =A0 "MPC85xxDS" - for a virtual machine for the e500v2 type platforms
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 and would support 85xx targets, plus P20=
20, P1022,etc
>>
>> =A0 "corenet-32-ds" - for a virtual machine similar to the 32-bit P4080
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 platforms
>>
>> =A0 "corenet-64-ds" - for a virtual machine based on a 64-bit corenet
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 platform
>
> I think we should drop the "DS" because that's a name applied to
> certain Freescale reference boards.
>
> Is being a CoreNet board really something meaningful with respect to
> KVM? =A0I don't see the connection.
>
> Also, if these are KVM creations, shouldn't there be a "kvm" in the
> compatible string somewhere?
I would say so. That would accurately describe the execution environment.
>
> --
> Timur Tabi
> Linux kernel developer at Freescale
>
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Fwd: [PATCH] powerpc: convert to generic pci_*_flags
From: Rob Herring @ 2011-07-09 2:25 UTC (permalink / raw)
To: linuxppc-dev
Posting to correct list email...
-------- Original Message --------
Subject: [PATCH] powerpc: convert to generic pci_*_flags
Date: Fri, 8 Jul 2011 21:21:24 -0500
From: Rob Herring <robherring2@gmail.com>
To: linuxppc-dev@lists.infradead.org
CC: Rob Herring <rob.herring@calxeda.com>, Benjamin Herrenschmidt
<benh@kernel.crashing.org>, Paul Mackerras <paulus@samba.org>,
linux-kernel@vger.kernel.org, nico@fluxnic.net, Jesse Barnes
<jbarnes@virtuousgeek.org>, Arnd Bergmann <arnd@arndb.de>,
monstr@monstr.eu, linuxram@us.ibm.com
From: Rob Herring <rob.herring@calxeda.com>
This converts powerpc to use generic pci_set/add/has_flags functions from
asm-generic/pci-bridge.h.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
---
Compiled on 86xx and G5.
This is part of a ARM PCI clean-up which moves the microblaze pci flags
functions to asm-generic/pci-bridge.h.
arch/powerpc/include/asm/pci-bridge.h | 50
+---------------------------
arch/powerpc/include/asm/pci.h | 2 +-
arch/powerpc/kernel/pci-common.c | 22 ++++++------
arch/powerpc/kernel/pci_32.c | 2 +-
arch/powerpc/kernel/pci_64.c | 4 +-
arch/powerpc/kernel/rtas_pci.c | 2 +-
arch/powerpc/platforms/40x/ep405.c | 2 +-
arch/powerpc/platforms/40x/ppc40x_simple.c | 2 +-
arch/powerpc/platforms/40x/walnut.c | 2 +-
arch/powerpc/platforms/44x/canyonlands.c | 2 +-
arch/powerpc/platforms/44x/ebony.c | 2 +-
arch/powerpc/platforms/44x/ppc44x_simple.c | 2 +-
arch/powerpc/platforms/44x/sam440ep.c | 2 +-
arch/powerpc/platforms/52xx/mpc52xx_pci.c | 2 +-
arch/powerpc/platforms/82xx/pq2.c | 2 +-
arch/powerpc/platforms/chrp/pci.c | 2 +-
arch/powerpc/platforms/powermac/pci.c | 6 ++--
arch/powerpc/sysdev/fsl_pci.c | 4 +-
arch/powerpc/sysdev/grackle.c | 2 +-
arch/powerpc/sysdev/ppc4xx_pci.c | 2 +-
20 files changed, 34 insertions(+), 82 deletions(-)
diff --git a/arch/powerpc/include/asm/pci-bridge.h
b/arch/powerpc/include/asm/pci-bridge.h
index b90dbf8..8a9cb9f 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -10,58 +10,10 @@
#include <linux/pci.h>
#include <linux/list.h>
#include <linux/ioport.h>
+#include <asm-generic/pci-bridge.h>
struct device_node;
-enum {
- /* Force re-assigning all resources (ignore firmware
- * setup completely)
- */
- PPC_PCI_REASSIGN_ALL_RSRC = 0x00000001,
-
- /* Re-assign all bus numbers */
- PPC_PCI_REASSIGN_ALL_BUS = 0x00000002,
-
- /* Do not try to assign, just use existing setup */
- PPC_PCI_PROBE_ONLY = 0x00000004,
-
- /* Don't bother with ISA alignment unless the bridge has
- * ISA forwarding enabled
- */
- PPC_PCI_CAN_SKIP_ISA_ALIGN = 0x00000008,
-
- /* Enable domain numbers in /proc */
- PPC_PCI_ENABLE_PROC_DOMAINS = 0x00000010,
- /* ... except for domain 0 */
- PPC_PCI_COMPAT_DOMAIN_0 = 0x00000020,
-};
-#ifdef CONFIG_PCI
-extern unsigned int ppc_pci_flags;
-
-static inline void ppc_pci_set_flags(int flags)
-{
- ppc_pci_flags = flags;
-}
-
-static inline void ppc_pci_add_flags(int flags)
-{
- ppc_pci_flags |= flags;
-}
-
-static inline int ppc_pci_has_flag(int flag)
-{
- return (ppc_pci_flags & flag);
-}
-#else
-static inline void ppc_pci_set_flags(int flags) { }
-static inline void ppc_pci_add_flags(int flags) { }
-static inline int ppc_pci_has_flag(int flag)
-{
- return 0;
-}
-#endif
-
-
/*
* Structure of a PCI controller (host bridge)
*/
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 7d77909..b9a40fa 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -44,7 +44,7 @@ struct pci_dev;
* bus numbers (don't do that on ppc64 yet !)
*/
#define pcibios_assign_all_busses() \
- (ppc_pci_has_flag(PPC_PCI_REASSIGN_ALL_BUS))
+ (pci_has_flag(PCI_REASSIGN_ALL_BUS))
static inline void pcibios_set_master(struct pci_dev *dev)
{
diff --git a/arch/powerpc/kernel/pci-common.c
b/arch/powerpc/kernel/pci-common.c
index 893af2a..4b9ae67 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -50,7 +50,7 @@ static int global_phb_number; /* Global phb counter */
resource_size_t isa_mem_base;
/* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */
-unsigned int ppc_pci_flags = 0;
+unsigned int pci_flags = 0;
static struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
@@ -842,9 +842,9 @@ int pci_proc_domain(struct pci_bus *bus)
{
struct pci_controller *hose = pci_bus_to_host(bus);
- if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS))
+ if (!pci_has_flag(PCI_ENABLE_PROC_DOMAINS))
return 0;
- if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0)
+ if (pci_has_flag(PCI_COMPAT_DOMAIN_0))
return hose->global_number != 0;
return 1;
}
@@ -920,13 +920,13 @@ static void __devinit
pcibios_fixup_resources(struct pci_dev *dev)
struct resource *res = dev->resource + i;
if (!res->flags)
continue;
- /* On platforms that have PPC_PCI_PROBE_ONLY set, we don't
+ /* On platforms that have PCI_PROBE_ONLY set, we don't
* consider 0 as an unassigned BAR value. It's technically
* a valid value, but linux doesn't like it... so when we can
* re-assign things, we do so, but if we can't, we keep it
* around and hope for the best...
*/
- if (res->start == 0 && !(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
+ if (res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY)) {
pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] is unassigned\n",
pci_name(dev), i,
(unsigned long long)res->start,
@@ -973,7 +973,7 @@ static int __devinit
pcibios_uninitialized_bridge_resource(struct pci_bus *bus,
int i;
/* We don't do anything if PCI_PROBE_ONLY is set */
- if (ppc_pci_flags & PPC_PCI_PROBE_ONLY)
+ if (pci_has_flag(PCI_PROBE_ONLY))
return 0;
/* Job is a bit different between memory and IO */
@@ -1146,7 +1146,7 @@ void __devinit pci_fixup_cardbus(struct pci_bus *bus)
static int skip_isa_ioresource_align(struct pci_dev *dev)
{
- if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) &&
+ if (pci_has_flag(PCI_CAN_SKIP_ISA_ALIGN) &&
!(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA))
return 1;
return 0;
@@ -1274,7 +1274,7 @@ void pcibios_allocate_bus_resources(struct pci_bus
*bus)
* and as such ensure proper re-allocation
* later.
*/
- if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)
+ if (pci_has_flag(PCI_REASSIGN_ALL_RSRC))
goto clear_resource;
pr = pci_find_parent_resource(bus->self, res);
if (pr == res) {
@@ -1459,7 +1459,7 @@ void __init pcibios_resource_survey(void)
list_for_each_entry(b, &pci_root_buses, node)
pcibios_allocate_bus_resources(b);
- if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) {
+ if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC)) {
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
}
@@ -1468,7 +1468,7 @@ void __init pcibios_resource_survey(void)
* the low IO area and the VGA memory area if they intersect the
* bus available resources to avoid allocating things on top of them
*/
- if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
+ if (!pci_has_flag(PCI_PROBE_ONLY)) {
list_for_each_entry(b, &pci_root_buses, node)
pcibios_reserve_legacy_regions(b);
}
@@ -1476,7 +1476,7 @@ void __init pcibios_resource_survey(void)
/* Now, if the platform didn't decide to blindly trust the firmware,
* we proceed to assigning things that were left unassigned
*/
- if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
+ if (!pci_has_flag(PCI_PROBE_ONLY)) {
pr_debug("PCI: Assigning unassigned resources...\n");
pci_assign_unassigned_resources();
}
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index bedb370..b1959bf 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -373,7 +373,7 @@ static int __init pcibios_init(void)
printk(KERN_INFO "PCI: Probing PCI hardware\n");
- if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS)
+ if (pci_has_flag(PCI_REASSIGN_ALL_BUS))
pci_assign_all_buses = 1;
/* Scan all of the recorded PCI controllers. */
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index fc6452b..ab34046 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -55,12 +55,12 @@ static int __init pcibios_init(void)
ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
if (pci_probe_only)
- ppc_pci_flags |= PPC_PCI_PROBE_ONLY;
+ pci_add_flags(PCI_PROBE_ONLY);
/* On ppc64, we always enable PCI domains and we keep domain 0
* backward compatible in /proc for video cards
*/
- ppc_pci_flags |= PPC_PCI_ENABLE_PROC_DOMAINS | PPC_PCI_COMPAT_DOMAIN_0;
+ pci_add_flags(PCI_ENABLE_PROC_DOMAINS | PCI_COMPAT_DOMAIN_0);
/* Scan all of the recorded PCI controllers. */
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 54e66da..6cd8f01 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -291,7 +291,7 @@ void __init find_and_init_phbs(void)
prop = of_get_property(of_chosen,
"linux,pci-assign-all-buses", NULL);
if (prop && *prop)
- ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
+ pci_add_flags(PCI_REASSIGN_ALL_BUS);
#endif /* CONFIG_PPC32 */
}
}
diff --git a/arch/powerpc/platforms/40x/ep405.c
b/arch/powerpc/platforms/40x/ep405.c
index 4058fd1..b0389bb 100644
--- a/arch/powerpc/platforms/40x/ep405.c
+++ b/arch/powerpc/platforms/40x/ep405.c
@@ -100,7 +100,7 @@ static void __init ep405_setup_arch(void)
/* Find & init the BCSR CPLD */
ep405_init_bcsr();
- ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
+ pci_set_flags(PCI_REASSIGN_ALL_RSRC);
}
static int __init ep405_probe(void)
diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c
b/arch/powerpc/platforms/40x/ppc40x_simple.c
index 2521d93..e8dd5c5 100644
--- a/arch/powerpc/platforms/40x/ppc40x_simple.c
+++ b/arch/powerpc/platforms/40x/ppc40x_simple.c
@@ -61,7 +61,7 @@ static const char *board[] __initdata = {
static int __init ppc40x_probe(void)
{
if (of_flat_dt_match(of_get_flat_dt_root(), board)) {
- ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
+ pci_set_flags(PCI_REASSIGN_ALL_RSRC);
return 1;
}
diff --git a/arch/powerpc/platforms/40x/walnut.c
b/arch/powerpc/platforms/40x/walnut.c
index 335df91..8b691df 100644
--- a/arch/powerpc/platforms/40x/walnut.c
+++ b/arch/powerpc/platforms/40x/walnut.c
@@ -51,7 +51,7 @@ static int __init walnut_probe(void)
if (!of_flat_dt_is_compatible(root, "ibm,walnut"))
return 0;
- ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
+ pci_set_flags(PCI_REASSIGN_ALL_RSRC);
return 1;
}
diff --git a/arch/powerpc/platforms/44x/canyonlands.c
b/arch/powerpc/platforms/44x/canyonlands.c
index afc5e8e..e300dd4 100644
--- a/arch/powerpc/platforms/44x/canyonlands.c
+++ b/arch/powerpc/platforms/44x/canyonlands.c
@@ -55,7 +55,7 @@ static int __init ppc460ex_probe(void)
{
unsigned long root = of_get_flat_dt_root();
if (of_flat_dt_is_compatible(root, "amcc,canyonlands")) {
- ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
+ pci_set_flags(PCI_REASSIGN_ALL_RSRC);
return 1;
}
return 0;
diff --git a/arch/powerpc/platforms/44x/ebony.c
b/arch/powerpc/platforms/44x/ebony.c
index 88b9117..6a4232b 100644
--- a/arch/powerpc/platforms/44x/ebony.c
+++ b/arch/powerpc/platforms/44x/ebony.c
@@ -54,7 +54,7 @@ static int __init ebony_probe(void)
if (!of_flat_dt_is_compatible(root, "ibm,ebony"))
return 0;
- ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
+ pci_set_flags(PCI_REASSIGN_ALL_RSRC);
return 1;
}
diff --git a/arch/powerpc/platforms/44x/ppc44x_simple.c
b/arch/powerpc/platforms/44x/ppc44x_simple.c
index c81c19c..8d22027 100644
--- a/arch/powerpc/platforms/44x/ppc44x_simple.c
+++ b/arch/powerpc/platforms/44x/ppc44x_simple.c
@@ -72,7 +72,7 @@ static int __init ppc44x_probe(void)
for (i = 0; i < ARRAY_SIZE(board); i++) {
if (of_flat_dt_is_compatible(root, board[i])) {
- ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
+ pci_set_flags(PCI_REASSIGN_ALL_RSRC);
return 1;
}
}
diff --git a/arch/powerpc/platforms/44x/sam440ep.c
b/arch/powerpc/platforms/44x/sam440ep.c
index a78e8eb..9e09b83 100644
--- a/arch/powerpc/platforms/44x/sam440ep.c
+++ b/arch/powerpc/platforms/44x/sam440ep.c
@@ -51,7 +51,7 @@ static int __init sam440ep_probe(void)
if (!of_flat_dt_is_compatible(root, "acube,sam440ep"))
return 0;
- ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
+ pci_set_flags(PCI_REASSIGN_ALL_RSRC);
return 1;
}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index da110bd..82051bd 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -371,7 +371,7 @@ mpc52xx_add_bridge(struct device_node *node)
pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name);
- ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
+ pci_add_flags(PCI_REASSIGN_ALL_BUS);
if (of_address_to_resource(node, 0, &rsrc) != 0) {
printk(KERN_ERR "Can't get %s resources\n", node->full_name);
diff --git a/arch/powerpc/platforms/82xx/pq2.c
b/arch/powerpc/platforms/82xx/pq2.c
index 9761a59..d111b02 100644
--- a/arch/powerpc/platforms/82xx/pq2.c
+++ b/arch/powerpc/platforms/82xx/pq2.c
@@ -53,7 +53,7 @@ static void __init pq2_pci_add_bridge(struct
device_node *np)
if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b)
goto err;
- ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
+ pci_add_flags(PCI_REASSIGN_ALL_BUS);
hose = pcibios_alloc_controller(np);
if (!hose)
diff --git a/arch/powerpc/platforms/chrp/pci.c
b/arch/powerpc/platforms/chrp/pci.c
index 8f67a39..f3376fa 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -199,7 +199,7 @@ static void __init setup_peg2(struct pci_controller
*hose, struct device_node *d
printk ("RTAS supporting Pegasos OF not found, please upgrade"
" your firmware\n");
}
- ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
+ pci_add_flags(PCI_REASSIGN_ALL_BUS);
/* keep the reference to the root node */
}
diff --git a/arch/powerpc/platforms/powermac/pci.c
b/arch/powerpc/platforms/powermac/pci.c
index f33e08d..c291afd 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -731,7 +731,7 @@ static void __init setup_bandit(struct
pci_controller *hose,
static int __init setup_uninorth(struct pci_controller *hose,
struct resource *addr)
{
- ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
+ pci_add_flags(PCI_REASSIGN_ALL_BUS);
has_uninorth = 1;
hose->ops = ¯isc_pci_ops;
hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
@@ -998,7 +998,7 @@ void __init pmac_pci_init(void)
struct device_node *np, *root;
struct device_node *ht = NULL;
- ppc_pci_set_flags(PPC_PCI_CAN_SKIP_ISA_ALIGN);
+ pci_set_flags(PCI_CAN_SKIP_ISA_ALIGN);
root = of_find_node_by_path("/");
if (root == NULL) {
@@ -1057,7 +1057,7 @@ void __init pmac_pci_init(void)
* some offset between bus number and domains for now when we
* assign all busses should help for now
*/
- if (ppc_pci_has_flag(PPC_PCI_REASSIGN_ALL_BUS))
+ if (pci_has_flag(PCI_REASSIGN_ALL_BUS))
pcibios_assign_bus_offset = 0x10;
#endif
}
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 68ca929..31f99ec7 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -343,7 +343,7 @@ int __init fsl_add_bridge(struct device_node *dev,
int is_primary)
printk(KERN_WARNING "Can't get bus-range for %s, assume"
" bus 0\n", dev->full_name);
- ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
+ pci_add_flags(PCI_REASSIGN_ALL_BUS);
hose = pcibios_alloc_controller(dev);
if (!hose)
return -ENOMEM;
@@ -679,7 +679,7 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
" bus 0\n", dev->full_name);
}
- ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
+ pci_add_flags(PCI_REASSIGN_ALL_BUS);
hose = pcibios_alloc_controller(dev);
if (!hose)
return -ENOMEM;
diff --git a/arch/powerpc/sysdev/grackle.c b/arch/powerpc/sysdev/grackle.c
index cf27df6..08abe91 100644
--- a/arch/powerpc/sysdev/grackle.c
+++ b/arch/powerpc/sysdev/grackle.c
@@ -57,7 +57,7 @@ void __init setup_grackle(struct pci_controller *hose)
{
setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0);
if (of_machine_is_compatible("PowerMac1,1"))
- ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
+ pci_add_flags(PCI_REASSIGN_ALL_BUS);
if (of_machine_is_compatible("AAPL,PowerBook1998"))
grackle_set_loop_snoop(hose, 1);
#if 0 /* Disabled for now, HW problems ??? */
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c
b/arch/powerpc/sysdev/ppc4xx_pci.c
index 156aa7d..9c067fa 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -1960,7 +1960,7 @@ static int __init ppc4xx_pci_find_bridges(void)
{
struct device_node *np;
- ppc_pci_flags |= PPC_PCI_ENABLE_PROC_DOMAINS | PPC_PCI_COMPAT_DOMAIN_0;
+ pci_add_flags(PCI_ENABLE_PROC_DOMAINS | PCI_COMPAT_DOMAIN_0);
#ifdef CONFIG_PPC4xx_PCI_EXPRESS
for_each_compatible_node(np, NULL, "ibm,plb-pciex")
--
1.7.4.1
^ permalink raw reply related
* Re: RFC: top level compatibles for virtual platforms
From: Tabi Timur-B04825 @ 2011-07-09 1:39 UTC (permalink / raw)
To: Yoder Stuart-B08248
Cc: Wood Scott-B07421, Alexander Graf, linuxppc-dev@ozlabs.org,
Gala Kumar-B11780
In-Reply-To: <9F6FE96B71CF29479FF1CDC8046E150316EAB6@039-SN1MPN1-003.039d.mgd.msft.net>
On Fri, Jul 8, 2011 at 1:43 PM, Yoder Stuart-B08248
<B08248@freescale.com> wrote:
> =A0 "MPC85xxDS" - for a virtual machine for the e500v2 type platforms
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 and would support 85xx targets, plus P202=
0, P1022,etc
>
> =A0 "corenet-32-ds" - for a virtual machine similar to the 32-bit P4080
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 platforms
>
> =A0 "corenet-64-ds" - for a virtual machine based on a 64-bit corenet
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 platform
I think we should drop the "DS" because that's a name applied to
certain Freescale reference boards.
Is being a CoreNet board really something meaningful with respect to
KVM? I don't see the connection.
Also, if these are KVM creations, shouldn't there be a "kvm" in the
compatible string somewhere?
--=20
Timur Tabi
Linux kernel developer at Freescale=
^ permalink raw reply
* [PATCH] [v3] tty/powerpc: introduce the ePAPR embedded hypervisor byte channel driver
From: Timur Tabi @ 2011-07-09 0:06 UTC (permalink / raw)
To: greg, linuxppc-dev, linux-kernel, linux-console
The ePAPR embedded hypervisor specification provides an API for "byte
channels", which are serial-like virtual devices for sending and receiving
streams of bytes. This driver provides Linux kernel support for byte
channels via three distinct interfaces:
1) An early-console (udbg) driver. This provides early console output
through a byte channel. The byte channel handle must be specified in a
Kconfig option.
2) A normal console driver. Output is sent to the byte channel designated
for stdout in the device tree. The console driver is for handling kernel
printk calls.
3) A tty driver, which is used to handle user-space input and output. The
byte channel used for the console is designated as the default tty.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
arch/powerpc/include/asm/udbg.h | 1 +
arch/powerpc/kernel/udbg.c | 2 +
drivers/tty/Kconfig | 34 ++
drivers/tty/Makefile | 1 +
drivers/tty/ehv_bytechan.c | 888 +++++++++++++++++++++++++++++++++++++++
5 files changed, 926 insertions(+), 0 deletions(-)
create mode 100644 drivers/tty/ehv_bytechan.c
diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h
index 58580e9..0938ac8 100644
--- a/arch/powerpc/include/asm/udbg.h
+++ b/arch/powerpc/include/asm/udbg.h
@@ -53,6 +53,7 @@ extern void __init udbg_init_40x_realmode(void);
extern void __init udbg_init_cpm(void);
extern void __init udbg_init_usbgecko(void);
extern void __init udbg_init_wsp(void);
+extern void __init udbg_init_ehv_bc(void);
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_UDBG_H */
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 23d65ab..e5e63a6 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -64,6 +64,8 @@ void __init udbg_early_init(void)
udbg_init_usbgecko();
#elif defined(CONFIG_PPC_EARLY_DEBUG_WSP)
udbg_init_wsp();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC)
+ udbg_init_ehv_bc();
#endif
#ifdef CONFIG_PPC_EARLY_DEBUG
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
index bd7cc05..f1ea59b 100644
--- a/drivers/tty/Kconfig
+++ b/drivers/tty/Kconfig
@@ -350,3 +350,37 @@ config TRACE_SINK
If you select this option, you need to select
"Trace data router for MIPI P1149.7 cJTAG standard".
+
+config PPC_EPAPR_HV_BYTECHAN
+ tristate "ePAPR hypervisor byte channel driver"
+ depends on PPC
+ help
+ This driver creates /dev entries for each ePAPR hypervisor byte
+ channel, thereby allowing applications to communicate with byte
+ channels as if they were serial ports.
+
+config PPC_EARLY_DEBUG_EHV_BC
+ bool "Early console (udbg) support for ePAPR hypervisors"
+ depends on PPC_EPAPR_HV_BYTECHAN
+ help
+ Select this option to enable early console (a.k.a. "udbg") support
+ via an ePAPR byte channel. You also need to choose the byte channel
+ handle below.
+
+config PPC_EARLY_DEBUG_EHV_BC_HANDLE
+ int "Byte channel handle for early console (udbg)"
+ depends on PPC_EARLY_DEBUG_EHV_BC
+ default 0
+ help
+ If you want early console (udbg) output through a byte channel,
+ specify the handle of the byte channel to use.
+
+ For this to work, the byte channel driver must be compiled
+ in-kernel, not as a module.
+
+ Note that only one early console driver can be enabled, so don't
+ enable any others if you enable this one.
+
+ If the number you specify is not a valid byte channel handle, then
+ there simply will be no early console output. This is true also
+ if you don't boot under a hypervisor at all.
diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile
index ea89b0b..2953059 100644
--- a/drivers/tty/Makefile
+++ b/drivers/tty/Makefile
@@ -26,5 +26,6 @@ obj-$(CONFIG_ROCKETPORT) += rocket.o
obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o
obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o
obj-$(CONFIG_SYNCLINK) += synclink.o
+obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o
obj-y += ipwireless/
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c
new file mode 100644
index 0000000..e67f70b
--- /dev/null
+++ b/drivers/tty/ehv_bytechan.c
@@ -0,0 +1,888 @@
+/* ePAPR hypervisor byte channel device driver
+ *
+ * Copyright 2009-2011 Freescale Semiconductor, Inc.
+ *
+ * Author: Timur Tabi <timur@freescale.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ * This driver support three distinct interfaces, all of which are related to
+ * ePAPR hypervisor byte channels.
+ *
+ * 1) An early-console (udbg) driver. This provides early console output
+ * through a byte channel. The byte channel handle must be specified in a
+ * Kconfig option.
+ *
+ * 2) A normal console driver. Output is sent to the byte channel designated
+ * for stdout in the device tree. The console driver is for handling kernel
+ * printk calls.
+ *
+ * 3) A tty driver, which is used to handle user-space input and output. The
+ * byte channel used for the console is designated as the default tty.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <asm/epapr_hcalls.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/circ_buf.h>
+#include <asm/udbg.h>
+
+/* The size of the transmit circular buffer. This must be a power of two. */
+#define BUF_SIZE 2048
+
+/* Per-byte channel private data */
+struct ehv_bc_data {
+ struct device *dev;
+ struct tty_port port;
+ uint32_t handle;
+ unsigned int rx_irq;
+ unsigned int tx_irq;
+
+ spinlock_t lock; /* lock for transmit buffer */
+ unsigned char buf[BUF_SIZE]; /* transmit circular buffer */
+ unsigned int head; /* circular buffer head */
+ unsigned int tail; /* circular buffer tail */
+
+ int tx_irq_enabled; /* true == TX interrupt is enabled */
+};
+
+/* Array of byte channel objects */
+static struct ehv_bc_data *bcs;
+
+/* Byte channel handle for stdout (and stdin), taken from device tree */
+static unsigned int stdout_bc;
+
+/* Virtual IRQ for the byte channel handle for stdin, taken from device tree */
+static unsigned int stdout_irq;
+
+/**************************** SUPPORT FUNCTIONS ****************************/
+
+/*
+ * Enable the transmit interrupt
+ *
+ * Unlike a serial device, byte channels have no mechanism for disabling their
+ * own receive or transmit interrupts. To emulate that feature, we toggle
+ * the IRQ in the kernel.
+ *
+ * We cannot just blindly call enable_irq() or disable_irq(), because these
+ * calls are reference counted. This means that we cannot call enable_irq()
+ * if interrupts are already enabled. This can happen in two situations:
+ *
+ * 1. The tty layer makes two back-to-back calls to ehv_bc_tty_write()
+ * 2. A transmit interrupt occurs while executing ehv_bc_tx_dequeue()
+ *
+ * To work around this, we keep a flag to tell us if the IRQ is enabled or not.
+ */
+static void enable_tx_interrupt(struct ehv_bc_data *bc)
+{
+ if (!bc->tx_irq_enabled) {
+ enable_irq(bc->tx_irq);
+ bc->tx_irq_enabled = 1;
+ }
+}
+
+static void disable_tx_interrupt(struct ehv_bc_data *bc)
+{
+ if (bc->tx_irq_enabled) {
+ disable_irq_nosync(bc->tx_irq);
+ bc->tx_irq_enabled = 0;
+ }
+}
+
+/*
+ * find the byte channel handle to use for the console
+ *
+ * The byte channel to be used for the console is specified via a "stdout"
+ * property in the /chosen node.
+ *
+ * For compatible with legacy device trees, we also look for a "stdout" alias.
+ */
+static int find_console_handle(void)
+{
+ struct device_node *np, *np2;
+ const char *sprop = NULL;
+ const uint32_t *iprop;
+
+ np = of_find_node_by_path("/chosen");
+ if (np)
+ sprop = of_get_property(np, "stdout-path", NULL);
+
+ if (!np || !sprop) {
+ of_node_put(np);
+ np = of_find_node_by_name(NULL, "aliases");
+ if (np)
+ sprop = of_get_property(np, "stdout", NULL);
+ }
+
+ if (!sprop) {
+ of_node_put(np);
+ return 0;
+ }
+
+ /* We don't care what the aliased node is actually called. We only
+ * care if it's compatible with "epapr,hv-byte-channel", because that
+ * indicates that it's a byte channel node. We use a temporary
+ * variable, 'np2', because we can't release 'np' until we're done with
+ * 'sprop'.
+ */
+ np2 = of_find_node_by_path(sprop);
+ of_node_put(np);
+ np = np2;
+ if (!np) {
+ pr_warning("ehv-bc: stdout node '%s' does not exist\n", sprop);
+ return 0;
+ }
+
+ /* Is it a byte channel? */
+ if (!of_device_is_compatible(np, "epapr,hv-byte-channel")) {
+ of_node_put(np);
+ return 0;
+ }
+
+ stdout_irq = irq_of_parse_and_map(np, 0);
+ if (stdout_irq == NO_IRQ) {
+ pr_err("ehv-bc: no 'interrupts' property in %s node\n", sprop);
+ of_node_put(np);
+ return 0;
+ }
+
+ /*
+ * The 'hv-handle' property contains the handle for this byte channel.
+ */
+ iprop = of_get_property(np, "hv-handle", NULL);
+ if (!iprop) {
+ pr_err("ehv-bc: no 'hv-handle' property in %s node\n",
+ np->name);
+ of_node_put(np);
+ return 0;
+ }
+ stdout_bc = be32_to_cpu(*iprop);
+
+ of_node_put(np);
+ return 1;
+}
+
+/*************************** EARLY CONSOLE DRIVER ***************************/
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_EHV_BC
+
+/*
+ * send a byte to a byte channel, wait if necessary
+ *
+ * This function sends a byte to a byte channel, and it waits and
+ * retries if the byte channel is full. It returns if the character
+ * has been sent, or if some error has occurred.
+ *
+ */
+static void byte_channel_spin_send(const char data)
+{
+ int ret, count;
+
+ do {
+ count = 1;
+ ret = ev_byte_channel_send(CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE,
+ &count, &data);
+ } while (ret == EV_EAGAIN);
+}
+
+/*
+ * The udbg subsystem calls this function to display a single character.
+ * We convert CR to a CR/LF.
+ */
+static void ehv_bc_udbg_putc(char c)
+{
+ if (c == '\n')
+ byte_channel_spin_send('\r');
+
+ byte_channel_spin_send(c);
+}
+
+/*
+ * early console initialization
+ *
+ * PowerPC kernels support an early printk console, also known as udbg.
+ * This function must be called via the ppc_md.init_early function pointer.
+ * At this point, the device tree has been unflattened, so we can obtain the
+ * byte channel handle for stdout.
+ *
+ * We only support displaying of characters (putc). We do not support
+ * keyboard input.
+ */
+void __init udbg_init_ehv_bc(void)
+{
+ unsigned int rx_count, tx_count;
+ unsigned int ret;
+
+ /* Check if we're running as a guest of a hypervisor */
+ if (!(mfmsr() & MSR_GS))
+ return;
+
+ /* Verify the byte channel handle */
+ ret = ev_byte_channel_poll(CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE,
+ &rx_count, &tx_count);
+ if (ret)
+ return;
+
+ udbg_putc = ehv_bc_udbg_putc;
+ register_early_udbg_console();
+
+ udbg_printf("ehv-bc: early console using byte channel handle %u\n",
+ CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE);
+}
+
+#endif
+
+/****************************** CONSOLE DRIVER ******************************/
+
+static struct tty_driver *ehv_bc_driver;
+
+/*
+ * Byte channel console sending worker function.
+ *
+ * For consoles, if the output buffer is full, we should just spin until it
+ * clears.
+ */
+static int ehv_bc_console_byte_channel_send(unsigned int handle, const char *s,
+ unsigned int count)
+{
+ unsigned int len;
+ int ret = 0;
+
+ while (count) {
+ len = min_t(unsigned int, count, EV_BYTE_CHANNEL_MAX_BYTES);
+ do {
+ ret = ev_byte_channel_send(handle, &len, s);
+ } while (ret == EV_EAGAIN);
+ count -= len;
+ s += len;
+ }
+
+ return ret;
+}
+
+/*
+ * write a string to the console
+ *
+ * This function gets called to write a string from the kernel, typically from
+ * a printk(). This function spins until all data is written.
+ *
+ * We copy the data to a temporary buffer because we need to insert a \r in
+ * front of every \n. It's more efficient to copy the data to the buffer than
+ * it is to make multiple hcalls for each character or each newline.
+ */
+static void ehv_bc_console_write(struct console *co, const char *s,
+ unsigned int count)
+{
+ unsigned int handle = (unsigned int)co->data;
+ char s2[EV_BYTE_CHANNEL_MAX_BYTES];
+ unsigned int i, j = 0;
+ char c;
+
+ for (i = 0; i < count; i++) {
+ c = *s++;
+
+ if (c == '\n')
+ s2[j++] = '\r';
+
+ s2[j++] = c;
+ if (j >= (EV_BYTE_CHANNEL_MAX_BYTES - 1)) {
+ if (ehv_bc_console_byte_channel_send(handle, s2, j))
+ return;
+ j = 0;
+ }
+ }
+
+ if (j)
+ ehv_bc_console_byte_channel_send(handle, s2, j);
+}
+
+/*
+ * When /dev/console is opened, the kernel iterates the console list looking
+ * for one with ->device and then calls that method. On success, it expects
+ * the passed-in int* to contain the minor number to use.
+ */
+static struct tty_driver *ehv_bc_console_device(struct console *co, int *index)
+{
+ *index = co->index;
+
+ return ehv_bc_driver;
+}
+
+static struct console ehv_bc_console = {
+ .name = "ttyEHV",
+ .write = ehv_bc_console_write,
+ .device = ehv_bc_console_device,
+ .flags = CON_PRINTBUFFER | CON_ENABLED,
+};
+
+/*
+ * Console initialization
+ *
+ * This is the first function that is called after the device tree is
+ * available, so here is where we determine the byte channel handle and IRQ for
+ * stdout/stdin, even though that information is used by the tty and character
+ * drivers.
+ */
+static int __init ehv_bc_console_init(void)
+{
+ if (!find_console_handle()) {
+ pr_debug("ehv-bc: stdout is not a byte channel\n");
+ return -ENODEV;
+ }
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_EHV_BC
+ /* Print a friendly warning if the user chose the wrong byte channel
+ * handle for udbg.
+ */
+ if (stdout_bc != CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE)
+ pr_warning("ehv-bc: udbg handle %u is not the stdout handle\n",
+ CONFIG_PPC_EARLY_DEBUG_EHV_BC_HANDLE);
+#endif
+
+ ehv_bc_console.data = (void *)stdout_bc;
+
+ /* add_preferred_console() must be called before register_console(),
+ otherwise it won't work. However, we don't want to enumerate all the
+ byte channels here, either, since we only care about one. */
+
+ add_preferred_console(ehv_bc_console.name, ehv_bc_console.index, NULL);
+ register_console(&ehv_bc_console);
+
+ pr_info("ehv-bc: registered console driver for byte channel %u\n",
+ stdout_bc);
+
+ return 0;
+}
+console_initcall(ehv_bc_console_init);
+
+/******************************** TTY DRIVER ********************************/
+
+/*
+ * byte channel receive interupt handler
+ *
+ * This ISR is called whenever data is available on a byte channel.
+ */
+static irqreturn_t ehv_bc_tty_rx_isr(int irq, void *data)
+{
+ struct ehv_bc_data *bc = data;
+ struct tty_struct *ttys = tty_port_tty_get(&bc->port);
+ unsigned int rx_count, tx_count, len;
+ int count;
+ char buffer[EV_BYTE_CHANNEL_MAX_BYTES];
+ int ret;
+
+ /* ttys could be NULL during a hangup */
+ if (!ttys)
+ return IRQ_HANDLED;
+
+ /* Find out how much data needs to be read, and then ask the TTY layer
+ * if it can handle that much. We want to ensure that every byte we
+ * read from the byte channel will be accepted by the TTY layer.
+ */
+ ev_byte_channel_poll(bc->handle, &rx_count, &tx_count);
+ count = tty_buffer_request_room(ttys, rx_count);
+
+ /* 'count' is the maximum amount of data the TTY layer can accept at
+ * this time. However, during testing, I was never able to get 'count'
+ * to be less than 'rx_count'. I'm not sure whether I'm calling it
+ * correctly.
+ */
+
+ while (count > 0) {
+ len = min_t(unsigned int, count, sizeof(buffer));
+
+ /* Read some data from the byte channel. This function will
+ * never return more than EV_BYTE_CHANNEL_MAX_BYTES bytes.
+ */
+ ev_byte_channel_receive(bc->handle, &len, buffer);
+
+ /* 'len' is now the amount of data that's been received. 'len'
+ * can't be zero, and most likely it's equal to one.
+ */
+
+ /* Pass the received data to the tty layer. */
+ ret = tty_insert_flip_string(ttys, buffer, len);
+
+ /* 'ret' is the number of bytes that the TTY layer accepted.
+ * If it's not equal to 'len', then it means the buffer is
+ * full, which should never happen. If it does happen, we can
+ * exit gracefully, but we drop the last 'len - ret' characters
+ * that we read from the byte channel.
+ */
+ if (ret != len)
+ break;
+
+ count -= len;
+ }
+
+ /* Tell the tty layer that we're done. */
+ tty_flip_buffer_push(ttys);
+
+ tty_kref_put(ttys);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * dequeue the transmit buffer to the hypervisor
+ *
+ * This function, which can be called in interrupt context, dequeues as much
+ * data as possible from the transmit buffer to the byte channel.
+ */
+static void ehv_bc_tx_dequeue(struct ehv_bc_data *bc)
+{
+ unsigned int count;
+ unsigned int len, ret;
+ unsigned long flags;
+
+ do {
+ spin_lock_irqsave(&bc->lock, flags);
+ len = min_t(unsigned int,
+ CIRC_CNT_TO_END(bc->head, bc->tail, BUF_SIZE),
+ EV_BYTE_CHANNEL_MAX_BYTES);
+
+ ret = ev_byte_channel_send(bc->handle, &len, bc->buf + bc->tail);
+
+ /* 'len' is valid only if the return code is 0 or EV_EAGAIN */
+ if (!ret || (ret == EV_EAGAIN))
+ bc->tail = (bc->tail + len) & (BUF_SIZE - 1);
+
+ count = CIRC_CNT(bc->head, bc->tail, BUF_SIZE);
+ spin_unlock_irqrestore(&bc->lock, flags);
+ } while (count && !ret);
+
+ spin_lock_irqsave(&bc->lock, flags);
+ if (CIRC_CNT(bc->head, bc->tail, BUF_SIZE))
+ /*
+ * If we haven't emptied the buffer, then enable the TX IRQ.
+ * We'll get an interrupt when there's more room in the
+ * hypervisor's output buffer.
+ */
+ enable_tx_interrupt(bc);
+ else
+ disable_tx_interrupt(bc);
+ spin_unlock_irqrestore(&bc->lock, flags);
+}
+
+/*
+ * byte channel transmit interupt handler
+ *
+ * This ISR is called whenever space becomes available for transmitting
+ * characters on a byte channel.
+ */
+static irqreturn_t ehv_bc_tty_tx_isr(int irq, void *data)
+{
+ struct ehv_bc_data *bc = data;
+ struct tty_struct *ttys = tty_port_tty_get(&bc->port);
+
+ ehv_bc_tx_dequeue(bc);
+ if (ttys) {
+ tty_wakeup(ttys);
+ tty_kref_put(ttys);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * This function is called when the tty layer has data for us send. We store
+ * the data first in a circular buffer, and then dequeue as much of that data
+ * as possible.
+ *
+ * We don't need to worry about whether there is enough room in the buffer for
+ * all the data. The purpose of ehv_bc_tty_write_room() is to tell the tty
+ * layer how much data it can safely send to us. We guarantee that
+ * ehv_bc_tty_write_room() will never lie, so the tty layer will never send us
+ * too much data.
+ */
+static int ehv_bc_tty_write(struct tty_struct *ttys, const unsigned char *s,
+ int count)
+{
+ struct ehv_bc_data *bc = ttys->driver_data;
+ unsigned long flags;
+ unsigned int len;
+ unsigned int written = 0;
+
+ while (1) {
+ spin_lock_irqsave(&bc->lock, flags);
+ len = CIRC_SPACE_TO_END(bc->head, bc->tail, BUF_SIZE);
+ if (count < len)
+ len = count;
+ if (len) {
+ memcpy(bc->buf + bc->head, s, len);
+ bc->head = (bc->head + len) & (BUF_SIZE - 1);
+ }
+ spin_unlock_irqrestore(&bc->lock, flags);
+ if (!len)
+ break;
+
+ s += len;
+ count -= len;
+ written += len;
+ }
+
+ ehv_bc_tx_dequeue(bc);
+
+ return written;
+}
+
+/*
+ * This function can be called multiple times for a given tty_struct, which is
+ * why we initialize bc->ttys in ehv_bc_tty_port_activate() instead.
+ *
+ * The tty layer will still call this function even if the device was not
+ * registered (i.e. tty_register_device() was not called). This happens
+ * because tty_register_device() is optional and some legacy drivers don't
+ * use it. So we need to check for that.
+ */
+static int ehv_bc_tty_open(struct tty_struct *ttys, struct file *filp)
+{
+ struct ehv_bc_data *bc = &bcs[ttys->index];
+
+ if (!bc->dev)
+ return -ENODEV;
+
+ return tty_port_open(&bc->port, ttys, filp);
+}
+
+/*
+ * Amazingly, if ehv_bc_tty_open() returns an error code, the tty layer will
+ * still call this function to close the tty device. So we can't assume that
+ * the tty port has been initialized.
+ */
+static void ehv_bc_tty_close(struct tty_struct *ttys, struct file *filp)
+{
+ struct ehv_bc_data *bc = &bcs[ttys->index];
+
+ if (bc->dev)
+ tty_port_close(&bc->port, ttys, filp);
+}
+
+/*
+ * Return the amount of space in the output buffer
+ *
+ * This is actually a contract between the driver and the tty layer outlining
+ * how much write room the driver can guarantee will be sent OR BUFFERED. This
+ * driver MUST honor the return value.
+ */
+static int ehv_bc_tty_write_room(struct tty_struct *ttys)
+{
+ struct ehv_bc_data *bc = ttys->driver_data;
+ unsigned long flags;
+ int count;
+
+ spin_lock_irqsave(&bc->lock, flags);
+ count = CIRC_SPACE(bc->head, bc->tail, BUF_SIZE);
+ spin_unlock_irqrestore(&bc->lock, flags);
+
+ return count;
+}
+
+/*
+ * Stop sending data to the tty layer
+ *
+ * This function is called when the tty layer's input buffers are getting full,
+ * so the driver should stop sending it data. The easiest way to do this is to
+ * disable the RX IRQ, which will prevent ehv_bc_tty_rx_isr() from being
+ * called.
+ *
+ * The hypervisor will continue to queue up any incoming data. If there is any
+ * data in the queue when the RX interrupt is enabled, we'll immediately get an
+ * RX interrupt.
+ */
+static void ehv_bc_tty_throttle(struct tty_struct *ttys)
+{
+ struct ehv_bc_data *bc = ttys->driver_data;
+
+ disable_irq(bc->rx_irq);
+}
+
+/*
+ * Resume sending data to the tty layer
+ *
+ * This function is called after previously calling ehv_bc_tty_throttle(). The
+ * tty layer's input buffers now have more room, so the driver can resume
+ * sending it data.
+ */
+static void ehv_bc_tty_unthrottle(struct tty_struct *ttys)
+{
+ struct ehv_bc_data *bc = ttys->driver_data;
+
+ /* If there is any data in the queue when the RX interrupt is enabled,
+ * we'll immediately get an RX interrupt.
+ */
+ enable_irq(bc->rx_irq);
+}
+
+static void ehv_bc_tty_hangup(struct tty_struct *ttys)
+{
+ struct ehv_bc_data *bc = ttys->driver_data;
+
+ ehv_bc_tx_dequeue(bc);
+ tty_port_hangup(&bc->port);
+}
+
+/*
+ * TTY driver operations
+ *
+ * If we could ask the hypervisor how much data is still in the TX buffer, or
+ * at least how big the TX buffers are, then we could implement the
+ * .wait_until_sent and .chars_in_buffer functions.
+ */
+static const struct tty_operations ehv_bc_ops = {
+ .open = ehv_bc_tty_open,
+ .close = ehv_bc_tty_close,
+ .write = ehv_bc_tty_write,
+ .write_room = ehv_bc_tty_write_room,
+ .throttle = ehv_bc_tty_throttle,
+ .unthrottle = ehv_bc_tty_unthrottle,
+ .hangup = ehv_bc_tty_hangup,
+};
+
+/*
+ * initialize the TTY port
+ *
+ * This function will only be called once, no matter how many times
+ * ehv_bc_tty_open() is called. That's why we register the ISR here, and also
+ * why we initialize tty_struct-related variables here.
+ */
+static int ehv_bc_tty_port_activate(struct tty_port *port,
+ struct tty_struct *ttys)
+{
+ struct ehv_bc_data *bc = container_of(port, struct ehv_bc_data, port);
+ int ret;
+
+ ttys->driver_data = bc;
+
+ ret = request_irq(bc->rx_irq, ehv_bc_tty_rx_isr, 0, "ehv-bc", bc);
+ if (ret < 0) {
+ dev_err(bc->dev, "could not request rx irq %u (ret=%i)\n",
+ bc->rx_irq, ret);
+ return ret;
+ }
+
+ /* request_irq also enables the IRQ */
+ bc->tx_irq_enabled = 1;
+
+ ret = request_irq(bc->tx_irq, ehv_bc_tty_tx_isr, 0, "ehv-bc", bc);
+ if (ret < 0) {
+ dev_err(bc->dev, "could not request tx irq %u (ret=%i)\n",
+ bc->tx_irq, ret);
+ free_irq(bc->rx_irq, bc);
+ return ret;
+ }
+
+ /* The TX IRQ is enabled only when we can't write all the data to the
+ * byte channel at once, so by default it's disabled.
+ */
+ disable_tx_interrupt(bc);
+
+ return 0;
+}
+
+static void ehv_bc_tty_port_shutdown(struct tty_port *port)
+{
+ struct ehv_bc_data *bc = container_of(port, struct ehv_bc_data, port);
+
+ free_irq(bc->tx_irq, bc);
+ free_irq(bc->rx_irq, bc);
+}
+
+static const struct tty_port_operations ehv_bc_tty_port_ops = {
+ .activate = ehv_bc_tty_port_activate,
+ .shutdown = ehv_bc_tty_port_shutdown,
+};
+
+static int __devinit ehv_bc_tty_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct ehv_bc_data *bc;
+ const uint32_t *iprop;
+ unsigned int handle;
+ int ret;
+ static unsigned int index = 1;
+ unsigned int i;
+
+ iprop = of_get_property(np, "hv-handle", NULL);
+ if (!iprop) {
+ dev_err(&pdev->dev, "no 'hv-handle' property in %s node\n",
+ np->name);
+ return -ENODEV;
+ }
+
+ /* We already told the console layer that the index for the console
+ * device is zero, so we need to make sure that we use that index when
+ * we probe the console byte channel node.
+ */
+ handle = be32_to_cpu(*iprop);
+ i = (handle == stdout_bc) ? 0 : index++;
+ bc = &bcs[i];
+
+ bc->handle = handle;
+ bc->head = 0;
+ bc->tail = 0;
+ spin_lock_init(&bc->lock);
+
+ bc->rx_irq = irq_of_parse_and_map(np, 0);
+ bc->tx_irq = irq_of_parse_and_map(np, 1);
+ if ((bc->rx_irq == NO_IRQ) || (bc->tx_irq == NO_IRQ)) {
+ dev_err(&pdev->dev, "no 'interrupts' property in %s node\n",
+ np->name);
+ ret = -ENODEV;
+ goto error;
+ }
+
+ bc->dev = tty_register_device(ehv_bc_driver, i, &pdev->dev);
+ if (IS_ERR(bc->dev)) {
+ ret = PTR_ERR(bc->dev);
+ dev_err(&pdev->dev, "could not register tty (ret=%i)\n", ret);
+ goto error;
+ }
+
+ tty_port_init(&bc->port);
+ bc->port.ops = &ehv_bc_tty_port_ops;
+
+ dev_set_drvdata(&pdev->dev, bc);
+
+ dev_info(&pdev->dev, "registered /dev/%s%u for byte channel %u\n",
+ ehv_bc_driver->name, i, bc->handle);
+
+ return 0;
+
+error:
+ irq_dispose_mapping(bc->tx_irq);
+ irq_dispose_mapping(bc->rx_irq);
+
+ memset(bc, 0, sizeof(struct ehv_bc_data));
+ return ret;
+}
+
+static int ehv_bc_tty_remove(struct platform_device *pdev)
+{
+ struct ehv_bc_data *bc = dev_get_drvdata(&pdev->dev);
+
+ tty_unregister_device(ehv_bc_driver, bc - bcs);
+
+ irq_dispose_mapping(bc->tx_irq);
+ irq_dispose_mapping(bc->rx_irq);
+
+ return 0;
+}
+
+static const struct of_device_id ehv_bc_tty_of_ids[] = {
+ { .compatible = "epapr,hv-byte-channel" },
+ {}
+};
+
+static struct platform_driver ehv_bc_tty_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ehv-bc",
+ .of_match_table = ehv_bc_tty_of_ids,
+ },
+ .probe = ehv_bc_tty_probe,
+ .remove = ehv_bc_tty_remove,
+};
+
+/**
+ * ehv_bc_init - ePAPR hypervisor byte channel driver initialization
+ *
+ * This function is called when this module is loaded.
+ */
+static int __init ehv_bc_init(void)
+{
+ struct device_node *np;
+ unsigned int count = 0; /* Number of elements in bcs[] */
+ int ret;
+
+ pr_info("ePAPR hypervisor byte channel driver\n");
+
+ /* Count the number of byte channels */
+ for_each_compatible_node(np, NULL, "epapr,hv-byte-channel")
+ count++;
+
+ if (!count)
+ return -ENODEV;
+
+ /* The array index of an element in bcs[] is the same as the tty index
+ * for that element. If you know the address of an element in the
+ * array, then you can use pointer math (e.g. "bc - bcs") to get its
+ * tty index.
+ */
+ bcs = kzalloc(count * sizeof(struct ehv_bc_data), GFP_KERNEL);
+ if (!bcs)
+ return -ENOMEM;
+
+ ehv_bc_driver = alloc_tty_driver(count);
+ if (!ehv_bc_driver) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ ehv_bc_driver->owner = THIS_MODULE;
+ ehv_bc_driver->driver_name = "ehv-bc";
+ ehv_bc_driver->name = ehv_bc_console.name;
+ ehv_bc_driver->type = TTY_DRIVER_TYPE_CONSOLE;
+ ehv_bc_driver->subtype = SYSTEM_TYPE_CONSOLE;
+ ehv_bc_driver->init_termios = tty_std_termios;
+ ehv_bc_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+ tty_set_operations(ehv_bc_driver, &ehv_bc_ops);
+
+ ret = tty_register_driver(ehv_bc_driver);
+ if (ret) {
+ pr_err("ehv-bc: could not register tty driver (ret=%i)\n", ret);
+ goto error;
+ }
+
+ ret = platform_driver_register(&ehv_bc_tty_driver);
+ if (ret) {
+ pr_err("ehv-bc: could not register platform driver (ret=%i)\n",
+ ret);
+ goto error;
+ }
+
+ return 0;
+
+error:
+ if (ehv_bc_driver) {
+ tty_unregister_driver(ehv_bc_driver);
+ put_tty_driver(ehv_bc_driver);
+ }
+
+ kfree(bcs);
+
+ return ret;
+}
+
+
+/**
+ * ehv_bc_exit - ePAPR hypervisor byte channel driver termination
+ *
+ * This function is called when this driver is unloaded.
+ */
+static void __exit ehv_bc_exit(void)
+{
+ tty_unregister_driver(ehv_bc_driver);
+ put_tty_driver(ehv_bc_driver);
+ kfree(bcs);
+}
+
+module_init(ehv_bc_init);
+module_exit(ehv_bc_exit);
+
+MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
+MODULE_DESCRIPTION("ePAPR hypervisor byte channel driver");
+MODULE_LICENSE("GPL v2");
--
1.7.4.4
^ permalink raw reply related
* Re: tty/powerpc: introduce the ePAPR embedded hypervisor byte channel driver
From: Greg KH @ 2011-07-08 22:29 UTC (permalink / raw)
To: Timur Tabi
Cc: arnd, kumar.gala, linux-kernel, akpm, linux-console, linuxppc-dev,
alan
In-Reply-To: <4E178193.2090905@freescale.com>
On Fri, Jul 08, 2011 at 05:15:47PM -0500, Timur Tabi wrote:
> Greg KH wrote:
> > Doesn't apply at all to the tty-next tree, so I can't apply it here :(
>
> Um, where exactly is the tty-next tree? The only thing I see that looks like it
> is this:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
>
> But the description of this tree says, "junk tree, please ignore".
Don't ignore it, that's the one :)
^ permalink raw reply
* Re: tty/powerpc: introduce the ePAPR embedded hypervisor byte channel driver
From: Timur Tabi @ 2011-07-08 22:15 UTC (permalink / raw)
To: Greg KH
Cc: arnd, kumar.gala, linux-kernel, akpm, linux-console, linuxppc-dev,
alan
In-Reply-To: <20110708220654.GA19146@kroah.com>
Greg KH wrote:
> Doesn't apply at all to the tty-next tree, so I can't apply it here :(
Um, where exactly is the tty-next tree? The only thing I see that looks like it
is this:
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
But the description of this tree says, "junk tree, please ignore".
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply
* Re: tty/powerpc: introduce the ePAPR embedded hypervisor byte channel driver
From: Timur Tabi @ 2011-07-08 22:12 UTC (permalink / raw)
To: Greg KH
Cc: arnd, kumar.gala, linux-kernel, akpm, linux-console, linuxppc-dev,
alan
In-Reply-To: <20110708220654.GA19146@kroah.com>
Greg KH wrote:
>> > 3) A tty driver, which is used to handle user-space input and output. The
>> > byte channel used for the console is designated as the default tty.
>> >
>> > Signed-off-by: Timur Tabi <timur@freescale.com>
> Doesn't apply at all to the tty-next tree, so I can't apply it here :(
I shall take care of that right now.
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply
* Re: tty/powerpc: introduce the ePAPR embedded hypervisor byte channel driver
From: Greg KH @ 2011-07-08 22:06 UTC (permalink / raw)
To: Timur Tabi
Cc: arnd, kumar.gala, linux-kernel, akpm, linux-console, linuxppc-dev,
alan
In-Reply-To: <1305830092-20104-1-git-send-email-timur@freescale.com>
On Thu, May 19, 2011 at 08:34:52AM -0000, Timur Tabi wrote:
> The ePAPR embedded hypervisor specification provides an API for "byte
> channels", which are serial-like virtual devices for sending and receiving
> streams of bytes. This driver provides Linux kernel support for byte
> channels via three distinct interfaces:
>
> 1) An early-console (udbg) driver. This provides early console output
> through a byte channel. The byte channel handle must be specified in a
> Kconfig option.
>
> 2) A normal console driver. Output is sent to the byte channel designated
> for stdout in the device tree. The console driver is for handling kernel
> printk calls.
>
> 3) A tty driver, which is used to handle user-space input and output. The
> byte channel used for the console is designated as the default tty.
>
> Signed-off-by: Timur Tabi <timur@freescale.com>
Doesn't apply at all to the tty-next tree, so I can't apply it here :(
^ permalink raw reply
* [PATCH] powerpc/mpic: add support for discontiguous cores
From: Timur Tabi @ 2011-07-08 21:12 UTC (permalink / raw)
To: linuxppc-dev
There is one place in the MPIC driver that assumes that the cores are numbered
from 0 to n-1. However, this is not true if the CPUs are not numbered
sequentially. This can happen on a eight-core SOC where cores two and three
are removed in the device tree. So instead of blindly looping, we iterate
over the discovered CPUs and use the SMP ID as the index.
This means that we no longer ask the MPIC how many CPUs there are, so
we also delete mpic->num_cpus.
We also catch if the number of CPUs in the SOC exceeds the number that the
MPIC supports. This should never happen, of course, but it's good to be
sure.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
arch/powerpc/include/asm/mpic.h | 2 --
arch/powerpc/sysdev/mpic.c | 24 +++++++++++++++---------
2 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index df18989..c447025 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -273,8 +273,6 @@ struct mpic
unsigned int irq_count;
/* Number of sources */
unsigned int num_sources;
- /* Number of CPUs */
- unsigned int num_cpus;
/* default senses array */
unsigned char *senses;
unsigned int senses_count;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 58d7a53..5d80573 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1321,13 +1321,11 @@ struct mpic * __init mpic_alloc(struct device_node *node,
mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
| MPIC_GREG_GCONF_MCK);
- /* Read feature register, calculate num CPUs and, for non-ISU
- * MPICs, num sources as well. On ISU MPICs, sources are counted
- * as ISUs are added
+ /*
+ * Read feature register. For non-ISU MPICs, num sources as well. On
+ * ISU MPICs, sources are counted as ISUs are added
*/
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 (flags & MPIC_BROKEN_FRR_NIRQS)
mpic->num_sources = mpic->irq_count;
@@ -1337,10 +1335,18 @@ struct mpic * __init mpic_alloc(struct device_node *node,
>> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;
}
+ /*
+ * The MPIC driver will crash if there are more cores than we
+ * can initialize, so we may as well catch that problem here.
+ */
+ BUG_ON(num_possible_cpus() > MPIC_MAX_CPUS);
+
/* Map the per-CPU registers */
- for (i = 0; i < mpic->num_cpus; i++) {
- mpic_map(mpic, node, paddr, &mpic->cpuregs[i],
- MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE),
+ for_each_possible_cpu(i) {
+ unsigned int cpu = get_hard_smp_processor_id(i);
+
+ mpic_map(mpic, node, paddr, &mpic->cpuregs[cpu],
+ MPIC_INFO(CPU_BASE) + cpu * MPIC_INFO(CPU_STRIDE),
0x1000);
}
@@ -1379,7 +1385,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
}
printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx,"
" max %d CPUs\n",
- name, vers, (unsigned long long)paddr, mpic->num_cpus);
+ name, vers, (unsigned long long)paddr, num_possible_cpus());
printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n",
mpic->isu_size, mpic->isu_shift, mpic->isu_mask);
--
1.7.3.4
^ permalink raw reply related
* RFC: top level compatibles for virtual platforms
From: Yoder Stuart-B08248 @ 2011-07-08 18:43 UTC (permalink / raw)
To: Grant Likely, Benjamin Herrenschmidt, Gala Kumar-B11780
Cc: Wood Scott-B07421, Alexander Graf, linuxppc-dev@ozlabs.org
With KVM on Freescale booke parts we have currently two general types of
virtual platforms-- 1) an 85xx-like platform with e500v2 cpus,
etc, and 2) a P4080-like platform with a corenet based bus.
Today QEMU passes through to the guest a device tree with
a top level compatible of either "MPC8544DS", or "fsl,P4080DS".
These work but neither is quite accurate this is used on all targets
regardless of the underlying physical hardware. Also, the guest
device tree represents virtual devices as well as a subset of the
cpus, memory, and devices on the hardware platform.
So continuing to use "MPC8544DS" or "fsl,P4080DS" compatible for all QEMU/K=
VM
created virtual machines is misleading and seems hackish. They are
compatible to a degree, but the virtual platform would typically
be quite different.
What do you all think about creating some new somewhat generic=20
machine types in Linux to represent these 2 types of virtual
platforms. Perhaps:
"MPC85xxDS" - for a virtual machine for the e500v2 type platforms
and would support 85xx targets, plus P2020, P1022,etc
"corenet-32-ds" - for a virtual machine similar to the 32-bit P4080
platforms
"corenet-64-ds" - for a virtual machine based on a 64-bit corenet
platform
Thoughts?
Thanks,
Stuart Yoder
^ permalink raw reply
* RE: [PATCH 1/2] booke/kprobe: make program exception to use one dedicated exception stack
From: Chen, Tiejun @ 2011-07-08 15:13 UTC (permalink / raw)
To: Chen, Tiejun, benh@kernel.crashing.org, linuxppc-dev@ozlabs.org
In-Reply-To: <1310119524-19672-1-git-send-email-tiejun.chen@windriver.com>
> -----Original Message-----
> From:=20
> linuxppc-dev-bounces+tiejun.chen=3Dwindriver.com@lists.ozlabs.or
> g=20
> [mailto:linuxppc-dev-bounces+tiejun.chen=3Dwindriver.com@lists.o
zlabs.org] On Behalf Of Tiejun Chen
> Sent: Friday, July 08, 2011 6:05 PM
> To: benh@kernel.crashing.org; linuxppc-dev@ozlabs.org
> Subject: [PATCH 1/2] booke/kprobe: make program exception to=20
> use one dedicated exception stack
>=20
> When kprobe these operations such as store-and-update-word for SP(r1),
>=20
> stwu r1, -A(r1)
>=20
> The program exception is triggered, and PPC always allocate=20
> an exception frame as shown as the follows:
>=20
> old r1 ----------
> ...
> nip
> gpr[2] ~ gpr[31]
> gpr[1] <--------- old r1 is stored.
> gpr[0]
> -------- <--------- pr_regs @offset 16 bytes
> padding
> STACK_FRAME_REGS_MARKER
> LR
> back chain
> new r1 ----------
> Then emulate_step() will emulate this instruction, 'stwu'.=20
> Actually its equivalent to:
> 1> Update pr_regs->gpr[1] =3D mem[old r1 + (-A)]
> 2> stw [old r1], mem[old r1 + (-A)]
>=20
> Please notice the stack based on new r1 may be covered with mem[old r1
> +(-A)] when addr[old r1 + (-A)] < addr[old r1 + sizeof(an=20
> exception frame0].
> So the above 2# operation will overwirte something to break=20
> this exception frame then unexpected kernel problem will be issued.
>=20
> So looks we have to implement independed interrupt stack for=20
> PPC program exception when CONFIG_BOOKE is enabled. Here we=20
> can use EXC_LEVEL_EXCEPTION_PROLOG to replace original=20
> NORMAL_EXCEPTION_PROLOG for program exception if=20
> CONFIG_BOOKE. Then its always safe for kprobe with independed=20
> exc stack from one pre-allocated and dedicated thread_info.
> Actually this is just waht we did for critical/machine check=20
> exceptions on PPC.
Update:
You can understand this problem completely from our previous email thread, =
about '[BUG?] 3.0-rc4+ftrace+kprobe: set kprobe at instruction 'stwu' lead=
to system crash/freeze'.=20
>=20
> Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
> ---
> arch/powerpc/include/asm/irq.h | 3 +++
> arch/powerpc/include/asm/reg.h | 4 ++++
> arch/powerpc/kernel/head_booke.h | 12 +++++++++++-
> arch/powerpc/kernel/irq.c | 11 +++++++++++
> arch/powerpc/kernel/setup_32.c | 4 ++++
> 5 files changed, 33 insertions(+), 1 deletions(-)
>=20
> diff --git a/arch/powerpc/include/asm/irq.h=20
> b/arch/powerpc/include/asm/irq.h index 1bff591..6d12169 100644
> --- a/arch/powerpc/include/asm/irq.h
> +++ b/arch/powerpc/include/asm/irq.h
> @@ -313,6 +313,9 @@ struct pt_regs;
> extern struct thread_info *critirq_ctx[NR_CPUS]; extern=20
> struct thread_info *dbgirq_ctx[NR_CPUS]; extern struct=20
> thread_info *mcheckirq_ctx[NR_CPUS];
> +#if defined(CONFIG_KPROBES) && defined(CONFIG_BOOKE) extern struct=20
> +thread_info *pgirq_ctx[NR_CPUS]; #endif
> extern void exc_lvl_ctx_init(void);
> #else
> #define exc_lvl_ctx_init()
> diff --git a/arch/powerpc/include/asm/reg.h=20
> b/arch/powerpc/include/asm/reg.h index c5cae0d..34d6178 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -885,6 +885,10 @@
> #endif
> #define SPRN_SPRG_RVCPU SPRN_SPRG1
> #define SPRN_SPRG_WVCPU SPRN_SPRG1
> +#ifdef CONFIG_KPROBES
> +#define SPRN_SPRG_RSCRATCH_PG SPRN_SPRG0
> +#define SPRN_SPRG_WSCRATCH_PG SPRN_SPRG0
> +#endif
> #endif
> =20
> #ifdef CONFIG_8xx
> diff --git a/arch/powerpc/kernel/head_booke.h=20
> b/arch/powerpc/kernel/head_booke.h
> index a0bf158..cf6cb1e 100644
> --- a/arch/powerpc/kernel/head_booke.h
> +++ b/arch/powerpc/kernel/head_booke.h
> @@ -79,6 +79,10 @@
> /* only on e500mc/e200 */
> #define DBG_STACK_BASE dbgirq_ctx
> =20
> +#if defined(CONFIG_KPROBES)
> +#define PG_STACK_BASE pgirq_ctx
> +#endif
> +
> #define EXC_LVL_FRAME_OVERHEAD (THREAD_SIZE -=20
> INT_FRAME_SIZE - EXC_LVL_SIZE)
> =20
> #ifdef CONFIG_SMP
> @@ -158,6 +162,12 @@
> EXC_LEVEL_EXCEPTION_PROLOG(DBG, SPRN_DSRR0,=20
> SPRN_DSRR1) #define MCHECK_EXCEPTION_PROLOG \
> EXC_LEVEL_EXCEPTION_PROLOG(MC, SPRN_MCSRR0, SPRN_MCSRR1)
> +#if defined(CONFIG_KPROBES)
> +#define PROGRAM_EXCEPTION_PROLOG \
> + EXC_LEVEL_EXCEPTION_PROLOG(PG, SPRN_SRR0,=20
> SPRN_SRR1) #else
> +#define PROGRAM_EXCEPTION_PROLOG NORMAL_EXCEPTION_PROLOG
> +#endif
> =20
> /*
> * Exception vectors.
> @@ -370,7 +380,7 @@ label:
> =20
> #define PROGRAM_EXCEPTION =09
> \
> START_EXCEPTION(Program) =09
> \
> - NORMAL_EXCEPTION_PROLOG; =09
> \
> + PROGRAM_EXCEPTION_PROLOG; =09
> \
> mfspr r4,SPRN_ESR; /* Grab the ESR and=20
> save it */ \
> stw r4,_ESR(r11); =09
> \
> addi r3,r1,STACK_FRAME_OVERHEAD; =09
> \
> diff --git a/arch/powerpc/kernel/irq.c=20
> b/arch/powerpc/kernel/irq.c index 5b428e3..ff5b8dd 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -397,6 +397,10 @@ struct thread_info =20
> *critirq_ctx[NR_CPUS] __read_mostly;
> struct thread_info *dbgirq_ctx[NR_CPUS] __read_mostly;
> struct thread_info *mcheckirq_ctx[NR_CPUS] __read_mostly;
> =20
> +#if defined(CONFIG_KPROBES) && defined(CONFIG_BOOKE)
> +struct thread_info *pgirq_ctx[NR_CPUS] __read_mostly;
> +#endif
> +
> void exc_lvl_ctx_init(void)
> {
> struct thread_info *tp;
> @@ -423,6 +427,13 @@ void exc_lvl_ctx_init(void)
> tp =3D mcheckirq_ctx[cpu_nr];
> tp->cpu =3D cpu_nr;
> tp->preempt_count =3D HARDIRQ_OFFSET;
> +
> +#if defined(CONFIG_KPROBES)
> + memset((void *)pgirq_ctx[i], 0, THREAD_SIZE);
> + tp =3D pgirq_ctx[i];
> + tp->cpu =3D i;
> + tp->preempt_count =3D 0;
> +#endif
> #endif
> }
> }
> diff --git a/arch/powerpc/kernel/setup_32.c=20
> b/arch/powerpc/kernel/setup_32.c index 620d792..f0c62ae 100644
> --- a/arch/powerpc/kernel/setup_32.c
> +++ b/arch/powerpc/kernel/setup_32.c
> @@ -272,6 +272,10 @@ static void __init exc_lvl_early_init(void)
> __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
> mcheckirq_ctx[hw_cpu] =3D (struct thread_info *)
> __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
> +#ifdef CONFIG_KPROBES
> + pgirq_ctx[i] =3D (struct thread_info *)
^
Next version I should replace 'i' with 'hw_cpu' like the above usage :)
Tiejun
> + __va(memblock_alloc(THREAD_SIZE,=20
> THREAD_SIZE)); #endif
> #endif
> }
> }
> --
> 1.5.6=
^ permalink raw reply
* SRAM @ FSL eLBC
From: Andre Schwarz @ 2011-07-08 13:55 UTC (permalink / raw)
To: LinuxPPC List
Hi,
I'd like to use a SRAM device (512K*8) connected to a MPC8377 localbus.
What's a decent way to do this (mmap'ed access) running v2.6.34 ?
Is platform RAM (drivers/mtd/maps/plat-ram.c) a good starting point ?
Any hints are welcome.
--
Regards,
Andre
MATRIX VISION GmbH, Talstrasse 16, DE-71570 Oppenweiler
Registergericht: Amtsgericht Stuttgart, HRB 271090
Geschaeftsfuehrer: Gerhard Thullner, Werner Armingeon, Uwe Furtner, Erhard Meier
^ permalink raw reply
* [git pull] Please pull powerpc.git next branch
From: Kumar Gala @ 2011-07-08 12:58 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
The following changes since commit af9719c3062dfe216a0c3de3fa52be6d22b4456c:
powerpc: Use -mtraceback=no (2011-07-01 13:49:27 +1000)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git next
Becky Bruce (1):
powerpc: Create next_tlbcam_idx percpu variable for FSL_BOOKE
Felix Radensky (1):
powerpc/p1022ds: Remove fixed-link property from ethernet nodes.
Kumar Gala (5):
powerpc/85xx: Add P3041 SoC device tree include stub
powerpc/85xx: Add P5020 SoC device tree include stub
driver core: Add ability for arch code to setup pdev_archdata
powerpc: implement arch_setup_pdev_archdata
powerpc: Dont require a dma_ops struct to set dma mask
Laurentiu TUDOR (1):
powerpc/85xx: Remove stale BUG_ON in mpc85xx_smp_init
Mingkai Hu (1):
powerpc/85xx: Add p2040 RDB board support
Timur Tabi (2):
drivers/virt: introduce Freescale hypervisor management driver
powerpc/85xx: add hypervisor config entries to corenet_smp_defconfig
Documentation/ioctl/ioctl-number.txt | 1 +
arch/powerpc/boot/dts/p1022ds.dts | 2 -
arch/powerpc/boot/dts/p2040rdb.dts | 166 +++++
arch/powerpc/boot/dts/p2040si.dtsi | 623 +++++++++++++++++
arch/powerpc/boot/dts/p3041ds.dts | 579 +----------------
arch/powerpc/boot/dts/p3041si.dtsi | 660 ++++++++++++++++++
arch/powerpc/boot/dts/p5020ds.dts | 571 +----------------
arch/powerpc/boot/dts/p5020si.dtsi | 652 ++++++++++++++++++
arch/powerpc/configs/corenet32_smp_defconfig | 4 +
arch/powerpc/include/asm/mmu.h | 5 +
arch/powerpc/kernel/dma.c | 4 +-
arch/powerpc/kernel/setup-common.c | 28 +-
arch/powerpc/kernel/smp.c | 4 +
arch/powerpc/mm/mem.c | 9 +
arch/powerpc/mm/tlb_nohash.c | 6 +
arch/powerpc/platforms/85xx/Kconfig | 12 +
arch/powerpc/platforms/85xx/Makefile | 1 +
arch/powerpc/platforms/85xx/p2040_rdb.c | 88 +++
arch/powerpc/platforms/85xx/smp.c | 9 +-
drivers/Kconfig | 2 +
drivers/Makefile | 3 +
drivers/base/platform.c | 21 +
drivers/of/platform.c | 4 +-
drivers/virt/Kconfig | 32 +
drivers/virt/Makefile | 5 +
drivers/virt/fsl_hypervisor.c | 937 ++++++++++++++++++++++++++
include/linux/Kbuild | 1 +
include/linux/fsl_hypervisor.h | 241 +++++++
include/linux/platform_device.h | 1 +
29 files changed, 3488 insertions(+), 1183 deletions(-)
create mode 100644 arch/powerpc/boot/dts/p2040rdb.dts
create mode 100644 arch/powerpc/boot/dts/p2040si.dtsi
create mode 100644 arch/powerpc/boot/dts/p3041si.dtsi
create mode 100644 arch/powerpc/boot/dts/p5020si.dtsi
create mode 100644 arch/powerpc/platforms/85xx/p2040_rdb.c
create mode 100644 drivers/virt/Kconfig
create mode 100644 drivers/virt/Makefile
create mode 100644 drivers/virt/fsl_hypervisor.c
create mode 100644 include/linux/fsl_hypervisor.h
^ permalink raw reply
* [PATCH 1/2] booke/kprobe: make program exception to use one dedicated exception stack
From: Tiejun Chen @ 2011-07-08 10:05 UTC (permalink / raw)
To: benh, linuxppc-dev
When kprobe these operations such as store-and-update-word for SP(r1),
stwu r1, -A(r1)
The program exception is triggered, and PPC always allocate an exception frame
as shown as the follows:
old r1 ----------
...
nip
gpr[2] ~ gpr[31]
gpr[1] <--------- old r1 is stored.
gpr[0]
-------- <--------- pr_regs @offset 16 bytes
padding
STACK_FRAME_REGS_MARKER
LR
back chain
new r1 ----------
Then emulate_step() will emulate this instruction, 'stwu'. Actually its
equivalent to:
1> Update pr_regs->gpr[1] = mem[old r1 + (-A)]
2> stw [old r1], mem[old r1 + (-A)]
Please notice the stack based on new r1 may be covered with mem[old r1
+(-A)] when addr[old r1 + (-A)] < addr[old r1 + sizeof(an exception frame0].
So the above 2# operation will overwirte something to break this exception
frame then unexpected kernel problem will be issued.
So looks we have to implement independed interrupt stack for PPC program
exception when CONFIG_BOOKE is enabled. Here we can use
EXC_LEVEL_EXCEPTION_PROLOG to replace original NORMAL_EXCEPTION_PROLOG
for program exception if CONFIG_BOOKE. Then its always safe for kprobe
with independed exc stack from one pre-allocated and dedicated thread_info.
Actually this is just waht we did for critical/machine check exceptions
on PPC.
Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
---
arch/powerpc/include/asm/irq.h | 3 +++
arch/powerpc/include/asm/reg.h | 4 ++++
arch/powerpc/kernel/head_booke.h | 12 +++++++++++-
arch/powerpc/kernel/irq.c | 11 +++++++++++
arch/powerpc/kernel/setup_32.c | 4 ++++
5 files changed, 33 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index 1bff591..6d12169 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -313,6 +313,9 @@ struct pt_regs;
extern struct thread_info *critirq_ctx[NR_CPUS];
extern struct thread_info *dbgirq_ctx[NR_CPUS];
extern struct thread_info *mcheckirq_ctx[NR_CPUS];
+#if defined(CONFIG_KPROBES) && defined(CONFIG_BOOKE)
+extern struct thread_info *pgirq_ctx[NR_CPUS];
+#endif
extern void exc_lvl_ctx_init(void);
#else
#define exc_lvl_ctx_init()
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index c5cae0d..34d6178 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -885,6 +885,10 @@
#endif
#define SPRN_SPRG_RVCPU SPRN_SPRG1
#define SPRN_SPRG_WVCPU SPRN_SPRG1
+#ifdef CONFIG_KPROBES
+#define SPRN_SPRG_RSCRATCH_PG SPRN_SPRG0
+#define SPRN_SPRG_WSCRATCH_PG SPRN_SPRG0
+#endif
#endif
#ifdef CONFIG_8xx
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index a0bf158..cf6cb1e 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -79,6 +79,10 @@
/* only on e500mc/e200 */
#define DBG_STACK_BASE dbgirq_ctx
+#if defined(CONFIG_KPROBES)
+#define PG_STACK_BASE pgirq_ctx
+#endif
+
#define EXC_LVL_FRAME_OVERHEAD (THREAD_SIZE - INT_FRAME_SIZE - EXC_LVL_SIZE)
#ifdef CONFIG_SMP
@@ -158,6 +162,12 @@
EXC_LEVEL_EXCEPTION_PROLOG(DBG, SPRN_DSRR0, SPRN_DSRR1)
#define MCHECK_EXCEPTION_PROLOG \
EXC_LEVEL_EXCEPTION_PROLOG(MC, SPRN_MCSRR0, SPRN_MCSRR1)
+#if defined(CONFIG_KPROBES)
+#define PROGRAM_EXCEPTION_PROLOG \
+ EXC_LEVEL_EXCEPTION_PROLOG(PG, SPRN_SRR0, SPRN_SRR1)
+#else
+#define PROGRAM_EXCEPTION_PROLOG NORMAL_EXCEPTION_PROLOG
+#endif
/*
* Exception vectors.
@@ -370,7 +380,7 @@ label:
#define PROGRAM_EXCEPTION \
START_EXCEPTION(Program) \
- NORMAL_EXCEPTION_PROLOG; \
+ PROGRAM_EXCEPTION_PROLOG; \
mfspr r4,SPRN_ESR; /* Grab the ESR and save it */ \
stw r4,_ESR(r11); \
addi r3,r1,STACK_FRAME_OVERHEAD; \
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 5b428e3..ff5b8dd 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -397,6 +397,10 @@ struct thread_info *critirq_ctx[NR_CPUS] __read_mostly;
struct thread_info *dbgirq_ctx[NR_CPUS] __read_mostly;
struct thread_info *mcheckirq_ctx[NR_CPUS] __read_mostly;
+#if defined(CONFIG_KPROBES) && defined(CONFIG_BOOKE)
+struct thread_info *pgirq_ctx[NR_CPUS] __read_mostly;
+#endif
+
void exc_lvl_ctx_init(void)
{
struct thread_info *tp;
@@ -423,6 +427,13 @@ void exc_lvl_ctx_init(void)
tp = mcheckirq_ctx[cpu_nr];
tp->cpu = cpu_nr;
tp->preempt_count = HARDIRQ_OFFSET;
+
+#if defined(CONFIG_KPROBES)
+ memset((void *)pgirq_ctx[i], 0, THREAD_SIZE);
+ tp = pgirq_ctx[i];
+ tp->cpu = i;
+ tp->preempt_count = 0;
+#endif
#endif
}
}
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 620d792..f0c62ae 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -272,6 +272,10 @@ static void __init exc_lvl_early_init(void)
__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
mcheckirq_ctx[hw_cpu] = (struct thread_info *)
__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
+#ifdef CONFIG_KPROBES
+ pgirq_ctx[i] = (struct thread_info *)
+ __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
+#endif
#endif
}
}
--
1.5.6
^ permalink raw reply related
* [PATCH 2/2] booke/kprobe: remove unnecessary preempt_enable_no_resched
From: Tiejun Chen @ 2011-07-08 10:05 UTC (permalink / raw)
To: benh, linuxppc-dev
In-Reply-To: <1310119524-19672-1-git-send-email-tiejun.chen@windriver.com>
When enable CONFIG_PREEMPT we will trigger the following call trace:
BUG: scheduling while atomic: swapper/1/0x10000000
...
krpobe always goes through the following path:
program_check_exception()
|
+ notify_die(DIE_BPT, "breakpoint",...)
|
+ kprobe_handler()
|
+ preempt_disable();
+ break_handler() <- preempt_enable_no_resched()
+ emulate_step()
+ preempt_enable_no_resched()
...
exit
We should remove unnecessary preempt_enable_no_resched() inside of break_handler()
since looks longjmp_break_handler() always go the above path.
Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
---
arch/powerpc/kernel/kprobes.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index bc47352..a8a2a4d 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -552,7 +552,6 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
* saved regs...
*/
memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
- preempt_enable_no_resched();
return 1;
}
--
1.5.6
^ permalink raw reply related
* Re: Analysing a kernel panic
From: Guillaume Dargaud @ 2011-07-08 7:26 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1310079493.14501.313.camel@pasglop>
> What is "Xad." ? (btw, coding style FAIL !)
That's the struct I use to access the control registers of the hardware.
About the coding style, don't worry it's never going to make it into mainstream as there's only one piece of that
hardware ever built ! (which is also why I didn't respect things like allowing multiple devices, please don't nail me to
the cross for that). And it's only my 2nd real Linux driver...
> Are you trying to write to HW registers using a structure like that
> without using the appropriate MMIO register accessors ?
> In that case, your accesses may happen our of order since you don't have
> memory barriers (among other potential problems).
Yes. I discovered the out() functions afterwards. But I insert asm(eieio) to avoid 'out of order' problems.
> The crash looks like you aren't properly clearing the interrupt
> condition on the HW, it remains asserted, tho it shouldn't overflow like
> that, something seems wrong with your PIC.
Is there some constraints I should tell the electronics guys ? Should the interrupt be raised for less than some max
duration ? It's on a raising signal, so I don't see why that should be an issue.
> What HW is this ? What PIC ? It looks like the interrupt source isn't
> masked on the PIC itself while it's being handled or something...
The hardware is a heavily modified Xilinx ML405 derivative.
The PIC is a XPS_INTC (in VHDL)
--
Guillaume Dargaud
http://www.gdargaud.net/Antarctica/
^ permalink raw reply
* [PATCH] powerpc/irq: Quieten irq mapping printks
From: Anton Blanchard @ 2011-07-08 6:35 UTC (permalink / raw)
To: benh, miltonm, michael; +Cc: linuxppc-dev
HFI creates interrupts each time a window is setup. This results in
a lot of messages in the kernel log buffer:
irq: irq 199007 on host null mapped to virtual irq 351
This box has over 3500 of them, causing more important kernel
messages to be overwritten. We can get at this information via
debugfs now so we may as well turn it into a pr_debug.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: linux-powerpc/arch/powerpc/kernel/irq.c
===================================================================
--- linux-powerpc.orig/arch/powerpc/kernel/irq.c 2011-07-08 08:49:44.288874115 +1000
+++ linux-powerpc/arch/powerpc/kernel/irq.c 2011-07-08 08:49:47.458927046 +1000
@@ -744,7 +744,7 @@ unsigned int irq_create_mapping(struct i
if (irq_setup_virq(host, virq, hwirq))
return NO_IRQ;
- printk(KERN_DEBUG "irq: irq %lu on host %s mapped to virtual irq %u\n",
+ pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n",
hwirq, host->of_node ? host->of_node->full_name : "null", virq);
return virq;
^ permalink raw reply
* Re: [PATCH v4 1/3] driver core: Add ability for arch code to setup pdev_archdata
From: Kumar Gala @ 2011-07-08 5:16 UTC (permalink / raw)
To: Greg KH; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20110708042235.GA26357@kroah.com>
On Jul 7, 2011, at 11:22 PM, Greg KH wrote:
> On Thu, Jul 07, 2011 at 11:00:41PM -0500, Kumar Gala wrote:
>> On some architectures we need to setup pdev_archdata before we add =
the
>> device. Waiting til a bus_notifier is too late since we might need =
the
>> pdev_archdata in the bus notifier. One example is setting up of =
dma_mask
>> pointers such that it can be used in a bus_notifier.
>>=20
>> We add weak noop version of arch_setup_pdev_archdata() and allow the =
arch
>> code to override with access the full definitions of struct device,
>> struct platform_device, and struct pdev_archdata.
>>=20
>> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
>> ---
>> v4:
>> * Move to use a weak function based on comments from Greg
>> v3:
>> * Add more comments and add missing call to arch_setup_pdev_archdata =
in
>> platform_device_register
>> v2:
>> * Added license, and comments about arch_setup_pdev_archdata()
>> per Mike's comments
>>=20
>> drivers/base/platform.c | 22 ++++++++++++++++++++++
>> include/linux/platform_device.h | 1 +
>> 2 files changed, 23 insertions(+), 0 deletions(-)
>>=20
>> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
>> index 1c291af..060686d 100644
>> --- a/drivers/base/platform.c
>> +++ b/drivers/base/platform.c
>> @@ -32,6 +32,26 @@ struct device platform_bus =3D {
>> EXPORT_SYMBOL_GPL(platform_bus);
>>=20
>> /**
>> + * arch_setup_pdev_archdata - Allow manipulation of archdata before =
its used
>> + * @dev: platform device
>> + *
>> + * This is called before platform_device_add() such that any =
pdev_archdata may
>> + * be setup before the platform_notifier is called. So if a user =
needs to
>> + * manipulate any relevant information in the pdev_archdata they can =
do:
>> + *
>> + * platform_devic_alloc()
>> + * ... manipulate ...
>> + * platform_device_add()
>> + *
>> + * And if they don't care they can just call =
platform_device_register() and
>> + * everything will just work out.
>> + */
>> +void __weak arch_setup_pdev_archdata(struct platform_device *pdev)
>> +{
>> + return ;
>> +}
>=20
> The "return" isn't needed, nor is the extra ' ' there, right? :)
yep, removed the ';' as well ;)
> Change that and you can take this through the ppc tree and add a:
> Acked-by: Greg Kroah-Hartman
> to them.
Ack added to all.
thanks
- k=
^ permalink raw reply
* Re: [PATCH v4 1/3] driver core: Add ability for arch code to setup pdev_archdata
From: Greg KH @ 2011-07-08 4:22 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1310097643-8414-1-git-send-email-galak@kernel.crashing.org>
On Thu, Jul 07, 2011 at 11:00:41PM -0500, Kumar Gala wrote:
> On some architectures we need to setup pdev_archdata before we add the
> device. Waiting til a bus_notifier is too late since we might need the
> pdev_archdata in the bus notifier. One example is setting up of dma_mask
> pointers such that it can be used in a bus_notifier.
>
> We add weak noop version of arch_setup_pdev_archdata() and allow the arch
> code to override with access the full definitions of struct device,
> struct platform_device, and struct pdev_archdata.
>
> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
> ---
> v4:
> * Move to use a weak function based on comments from Greg
> v3:
> * Add more comments and add missing call to arch_setup_pdev_archdata in
> platform_device_register
> v2:
> * Added license, and comments about arch_setup_pdev_archdata()
> per Mike's comments
>
> drivers/base/platform.c | 22 ++++++++++++++++++++++
> include/linux/platform_device.h | 1 +
> 2 files changed, 23 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index 1c291af..060686d 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -32,6 +32,26 @@ struct device platform_bus = {
> EXPORT_SYMBOL_GPL(platform_bus);
>
> /**
> + * arch_setup_pdev_archdata - Allow manipulation of archdata before its used
> + * @dev: platform device
> + *
> + * This is called before platform_device_add() such that any pdev_archdata may
> + * be setup before the platform_notifier is called. So if a user needs to
> + * manipulate any relevant information in the pdev_archdata they can do:
> + *
> + * platform_devic_alloc()
> + * ... manipulate ...
> + * platform_device_add()
> + *
> + * And if they don't care they can just call platform_device_register() and
> + * everything will just work out.
> + */
> +void __weak arch_setup_pdev_archdata(struct platform_device *pdev)
> +{
> + return ;
> +}
The "return" isn't needed, nor is the extra ' ' there, right? :)
Change that and you can take this through the ppc tree and add a:
Acked-by: Greg Kroah-Hartman
to them.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH 4/5] powerpc: Create next_tlbcam_idx percpu variable for FSL_BOOKE
From: Kumar Gala @ 2011-07-08 4:13 UTC (permalink / raw)
To: Becky Bruce; +Cc: linuxppc-dev, linux-kernel, wli, david
In-Reply-To: <13092911313115-git-send-email-beckyb@kernel.crashing.org>
On Jun 28, 2011, at 2:54 PM, Becky Bruce wrote:
> From: Becky Bruce <beckyb@kernel.crashing.org>
>
> This is used to round-robin TLBCAM entries.
>
> Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org>
> ---
> arch/powerpc/include/asm/mmu.h | 5 +++++
> arch/powerpc/kernel/smp.c | 4 ++++
> arch/powerpc/mm/mem.c | 9 +++++++++
> arch/powerpc/mm/tlb_nohash.c | 6 ++++++
> 4 files changed, 24 insertions(+), 0 deletions(-)
applied to next
- k
^ permalink raw reply
* Re: [PATCH] powerpc/85xx: Add p2040 RDB board support
From: Kumar Gala @ 2011-07-08 4:12 UTC (permalink / raw)
To: Mingkai Hu; +Cc: linuxppc-dev
In-Reply-To: <1309247554-13580-1-git-send-email-Mingkai.hu@freescale.com>
On Jun 28, 2011, at 2:52 AM, Mingkai Hu wrote:
> P2040RDB Specification:
> -----------------------
> 2Gbyte unbuffered DDR3 SDRAM SO-DIMM(64bit bus)
> 128 Mbyte NOR flash single-chip memory
> 256 Kbit M24256 I2C EEPROM
> 16 Mbyte SPI memory
> SD connector to interface with the SD memory card
> dTSEC1: connected to the Vitesse SGMII PHY (VSC8221)
> dTSEC2: connected to the Vitesse SGMII PHY (VSC8221)
> dTSEC3: connected to the Vitesse SGMII PHY (VSC8221)
> dTSEC4: connected to the Vitesse RGMII PHY (VSC8641)
> dTSEC5: connected to the Vitesse RGMII PHY (VSC8641)
> I2C1: Real time clock, Temperature sensor
> I2C2: Vcore Regulator, 256Kbit I2C Bus EEPROM
> SATA: Lanes C and Land D of Bank2 are connected to two SATA connectors
> UART: supports two UARTs up to 115200 bps for console
> USB 2.0: connected via a internal UTMI PHY to two TYPE-A interfaces
> PCIe:
> - Lanes E, F, G and H of Bank1 are connected to one x4 PCIe SLOT1
> - Lanes C and Land D of Bank2 are connected to one x4 PCIe SLOT2
>=20
> Signed-off-by: Mingkai Hu <Mingkai.hu@freescale.com>
> ---
> Based on =
http://git.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git
>=20
> arch/powerpc/boot/dts/p2040rdb.dts | 166 +++++++
> arch/powerpc/boot/dts/p2040si.dtsi | 623 =
++++++++++++++++++++++++++
> arch/powerpc/configs/corenet32_smp_defconfig | 1 +
> arch/powerpc/platforms/85xx/Kconfig | 12 +
> arch/powerpc/platforms/85xx/Makefile | 1 +
> arch/powerpc/platforms/85xx/p2040_rdb.c | 88 ++++
> 6 files changed, 891 insertions(+), 0 deletions(-)
> create mode 100644 arch/powerpc/boot/dts/p2040rdb.dts
> create mode 100644 arch/powerpc/boot/dts/p2040si.dtsi
> create mode 100644 arch/powerpc/platforms/85xx/p2040_rdb.c
applied to next
- k
^ permalink raw reply
* Re: [PATCH] powerpc/p1022ds: Remove fixed-link property from ethernet nodes.
From: Kumar Gala @ 2011-07-08 4:12 UTC (permalink / raw)
To: Felix Radensky; +Cc: linuxppc-dev, B04825
In-Reply-To: <1310024270-2675-1-git-send-email-felix@embedded-sol.com>
On Jul 7, 2011, at 2:37 AM, Felix Radensky wrote:
> On P1022DS both ethernet controllers are connected to RGMII PHYs
> accessible via MDIO bus. Remove fixed-link property from ethernet
> nodes as they only required when fixed link PHYs without MDIO bus
> are used.
>
> Signed-off-by: Felix Radensky <felix@embedded-sol.com>
> ---
> arch/powerpc/boot/dts/p1022ds.dts | 2 --
> 1 files changed, 0 insertions(+), 2 deletions(-)
applied to next
^ permalink raw reply
* Re: [PATCH] Remove a BUG_ON that triggered when running under FSL Hypervisor
From: Kumar Gala @ 2011-07-08 4:12 UTC (permalink / raw)
To: Laurentiu TUDOR; +Cc: linuxppc-dev
In-Reply-To: <1310046270-6654-1-git-send-email-Laurentiu.Tudor@freescale.com>
On Jul 7, 2011, at 8:44 AM, Laurentiu TUDOR wrote:
> mpc85xx_smp_init platform init function assumed that smp_ops.message_pass
> was set to default arch dependent smp_muxed_ipi_message_pass.
> However this does not seem to happen. Moreover, the arch specific code
> in arch/powerpc/kernel/smp.c handles smp_ops.message_pass == NULL and if so
> calls the default implementation.
>
> Signed-off-by: Laurentiu TUDOR <Laurentiu.Tudor@freescale.com>
> ---
> arch/powerpc/platforms/85xx/smp.c | 9 +++++----
> 1 files changed, 5 insertions(+), 4 deletions(-)
Re-worded commit message a bit, applied to next
- k
^ permalink raw reply
* Re: [PATCH v3 1/3] driver core: Add ability for arch code to setup pdev_archdata
From: Kumar Gala @ 2011-07-08 4:03 UTC (permalink / raw)
To: Greg KH; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20110707141125.GE27648@kroah.com>
On Jul 7, 2011, at 9:11 AM, Greg KH wrote:
> On Thu, Jul 07, 2011 at 08:55:44AM -0500, Kumar Gala wrote:
>>=20
>> On Jul 1, 2011, at 5:09 PM, Greg KH wrote:
>>=20
>>> On Thu, Jun 23, 2011 at 06:33:57AM -0500, Kumar Gala wrote:
>>>> On some architectures we need to setup pdev_archdata before we add =
the
>>>> device. Waiting til a bus_notifier is too late since we might need =
the
>>>> pdev_archdata in the bus notifier. One example is setting up of =
dma_mask
>>>> pointers such that it can be used in a bus_notifier.
>>>>=20
>>>> We add noop version of arch_setup_pdev_archdata() in
>>>> <asm-generic/platform_device.h> and allow the arch code to override =
with
>>>> access the full definitions of struct device, struct =
platform_device, and
>>>> struct pdev_archdata.
>>>=20
>>> Isn't there some way to use "weak" symbols to keep us from having to
>>> create this .h file in every single arch and then if the arch wants =
to
>>> define it, it does so?
>>>=20
>>> That should make this patch simpler, right?
>>>=20
>>> thanks,
>>>=20
>>> greg k-h
>>=20
>> Changing to weak should be doable if we are ok with the additional
>> function call always happening.
>=20
> Given that this is not a fast path, and the function call for the
> "normal" case would do nothing, it should be fine, right?
>=20
> greg k-h
Sounds good, new version sent that uses weak instead. If this looks =
good let me know if you just want to ACK and send via powerpc.git tree =
or if you'll pick these up.
- k
^ permalink raw reply
* [PATCH v4 3/3] powerpc: Dont require a dma_ops struct to set dma mask
From: Kumar Gala @ 2011-07-08 4:00 UTC (permalink / raw)
To: Greg KH; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1310097643-8414-2-git-send-email-galak@kernel.crashing.org>
The only reason to require a dma_ops struct is to see if it has
implemented set_dma_mask. If not we can fall back to setting the mask
directly.
This resolves an issue with how to sequence the setting of a DMA mask
for platform devices. Before we had an issue in that we have no way of
setting the DMA mask before the various low level bus notifiers get
called that might check it (swiotlb).
So now we can do:
pdev = platform_device_alloc("foobar", 0);
dma_set_mask(&pdev->dev, DMA_BIT_MASK(37));
platform_device_add(pdev);
And expect the right thing to happen with the bus notifiers get called
via platform_device_add.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
arch/powerpc/kernel/dma.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index d238c08..4f0959f 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -161,9 +161,7 @@ int dma_set_mask(struct device *dev, u64 dma_mask)
if (ppc_md.dma_set_mask)
return ppc_md.dma_set_mask(dev, dma_mask);
- if (unlikely(dma_ops == NULL))
- return -EIO;
- if (dma_ops->set_dma_mask != NULL)
+ if ((dma_ops != NULL) && (dma_ops->set_dma_mask != NULL))
return dma_ops->set_dma_mask(dev, dma_mask);
if (!dev->dma_mask || !dma_supported(dev, dma_mask))
return -EIO;
--
1.7.3.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox