Merge branch 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6
* 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6: (63 commits) of/platform: Register of_platform_drivers with an "of:" prefix of/address: Clean up function declarations of/spi: call of_register_spi_devices() from spi core code of: Provide default of_node_to_nid() implementation. of/device: Make of_device_make_bus_id() usable by other code. of/irq: Fix endian issues in parsing interrupt specifiers of: Fix phandle endian issues of/flattree: fix of_flat_dt_is_compatible() to match the full compatible string of: remove of_default_bus_ids of: make of_find_device_by_node generic microblaze: remove references to of_device and to_of_device sparc: remove references to of_device and to_of_device powerpc: remove references to of_device and to_of_device of/device: Replace of_device with platform_device in includes and core code of/device: Protect against binding of_platform_drivers to non-OF devices of: remove asm/of_device.h of: remove asm/of_platform.h of/platform: remove all of_bus_type and of_platform_bus_type references of: Merge of_platform_bus_type with platform_bus_type drivercore/of: Add OF style matching to platform bus ... Fix up trivial conflicts in arch/microblaze/kernel/Makefile due to just some obj-y removals by the devicetree branch, while the microblaze updates added a new file.
This commit is contained in:
Коммит
03c0c29aff
|
@ -18,6 +18,8 @@ config MICROBLAZE
|
|||
select HAVE_DMA_ATTRS
|
||||
select HAVE_DMA_API_DEBUG
|
||||
select TRACING_SUPPORT
|
||||
select OF
|
||||
select OF_FLATTREE
|
||||
|
||||
config SWAP
|
||||
def_bool n
|
||||
|
@ -76,9 +78,6 @@ config LOCKDEP_SUPPORT
|
|||
config HAVE_LATENCYTOP_SUPPORT
|
||||
def_bool y
|
||||
|
||||
config DTC
|
||||
def_bool y
|
||||
|
||||
source "init/Kconfig"
|
||||
|
||||
source "kernel/Kconfig.freezer"
|
||||
|
@ -125,18 +124,6 @@ config CMDLINE_FORCE
|
|||
Set this to have arguments from the default kernel command string
|
||||
override those passed by the boot loader.
|
||||
|
||||
config OF
|
||||
def_bool y
|
||||
select OF_FLATTREE
|
||||
|
||||
config PROC_DEVICETREE
|
||||
bool "Support for device tree in /proc"
|
||||
depends on PROC_FS
|
||||
help
|
||||
This option adds a device-tree directory under /proc which contains
|
||||
an image of the device tree that the kernel copies from Open
|
||||
Firmware or other boot firmware. If unsure, say Y here.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Advanced setup"
|
||||
|
|
|
@ -27,17 +27,6 @@ extern unsigned int nr_irq;
|
|||
struct pt_regs;
|
||||
extern void do_IRQ(struct pt_regs *regs);
|
||||
|
||||
/**
|
||||
* irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
|
||||
* @device: Device node of the device whose interrupt is to be mapped
|
||||
* @index: Index of the interrupt to map
|
||||
*
|
||||
* This function is a wrapper that chains of_irq_map_one() and
|
||||
* irq_create_of_mapping() to make things easier to callers
|
||||
*/
|
||||
struct device_node;
|
||||
extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index);
|
||||
|
||||
/** FIXME - not implement
|
||||
* irq_dispose_mapping - Unmap an interrupt
|
||||
* @virq: linux virq number of the interrupt to unmap
|
||||
|
@ -62,17 +51,4 @@ struct irq_host;
|
|||
extern unsigned int irq_create_mapping(struct irq_host *host,
|
||||
irq_hw_number_t hwirq);
|
||||
|
||||
/**
|
||||
* irq_create_of_mapping - Map a hardware interrupt into linux virq space
|
||||
* @controller: Device node of the interrupt controller
|
||||
* @inspec: Interrupt specifier from the device-tree
|
||||
* @intsize: Size of the interrupt specifier from the device-tree
|
||||
*
|
||||
* This function is identical to irq_create_mapping except that it takes
|
||||
* as input informations straight from the device-tree (typically the results
|
||||
* of the of_irq_map_*() functions.
|
||||
*/
|
||||
extern unsigned int irq_create_of_mapping(struct device_node *controller,
|
||||
u32 *intspec, unsigned int intsize);
|
||||
|
||||
#endif /* _ASM_MICROBLAZE_IRQ_H */
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
|
||||
*
|
||||
* based on PowerPC of_device.h
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_MICROBLAZE_OF_DEVICE_H
|
||||
#define _ASM_MICROBLAZE_OF_DEVICE_H
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
/*
|
||||
* The of_device is a kind of "base class" that is a superset of
|
||||
* struct device for use by devices attached to an OF node and
|
||||
* probed using OF properties.
|
||||
*/
|
||||
struct of_device {
|
||||
struct device dev; /* Generic device interface */
|
||||
struct pdev_archdata archdata;
|
||||
};
|
||||
|
||||
extern ssize_t of_device_get_modalias(struct of_device *ofdev,
|
||||
char *str, ssize_t len);
|
||||
|
||||
extern struct of_device *of_device_alloc(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent);
|
||||
|
||||
extern int of_device_uevent(struct device *dev,
|
||||
struct kobj_uevent_env *env);
|
||||
|
||||
extern void of_device_make_bus_id(struct of_device *dev);
|
||||
|
||||
/* This is just here during the transition */
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_MICROBLAZE_OF_DEVICE_H */
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
*
|
||||
* 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_MICROBLAZE_OF_PLATFORM_H
|
||||
#define _ASM_MICROBLAZE_OF_PLATFORM_H
|
||||
|
||||
/* This is just here during the transition */
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
/*
|
||||
* The list of OF IDs below is used for matching bus types in the
|
||||
* system whose devices are to be exposed as of_platform_devices.
|
||||
*
|
||||
* This is the default list valid for most platforms. This file provides
|
||||
* functions who can take an explicit list if necessary though
|
||||
*
|
||||
* The search is always performed recursively looking for children of
|
||||
* the provided device_node and recursively if such a children matches
|
||||
* a bus type in the list
|
||||
*/
|
||||
|
||||
static const struct of_device_id of_default_bus_ids[] = {
|
||||
{ .type = "soc", },
|
||||
{ .compatible = "soc", },
|
||||
{ .type = "plb5", },
|
||||
{ .type = "plb4", },
|
||||
{ .type = "opb", },
|
||||
{ .type = "simple", },
|
||||
{},
|
||||
};
|
||||
|
||||
/* Platform devices and busses creation */
|
||||
extern struct of_device *of_platform_device_create(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent);
|
||||
/* pseudo "matches" value to not do deep probe */
|
||||
#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
|
||||
|
||||
extern int of_platform_bus_probe(struct device_node *root,
|
||||
const struct of_device_id *matches,
|
||||
struct device *parent);
|
||||
|
||||
extern struct of_device *of_find_device_by_phandle(phandle ph);
|
||||
|
||||
extern void of_instantiate_rtc(void);
|
||||
|
||||
#endif /* _ASM_MICROBLAZE_OF_PLATFORM_H */
|
|
@ -47,13 +47,6 @@
|
|||
#define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1)))
|
||||
#define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1)))
|
||||
|
||||
/* align addr on a size boundary - adjust address up/down if needed */
|
||||
#define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1)))
|
||||
#define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1)))
|
||||
|
||||
/* align addr on a size boundary - adjust address up if needed */
|
||||
#define _ALIGN(addr, size) _ALIGN_UP(addr, size)
|
||||
|
||||
#ifndef CONFIG_MMU
|
||||
/*
|
||||
* PAGE_OFFSET -- the first address of the first page of memory. When not
|
||||
|
|
|
@ -172,13 +172,8 @@ static inline int pci_has_flag(int flag)
|
|||
|
||||
extern struct list_head hose_list;
|
||||
|
||||
extern unsigned long pci_address_to_pio(phys_addr_t address);
|
||||
extern int pcibios_vaddr_is_ioport(void __iomem *address);
|
||||
#else
|
||||
static inline unsigned long pci_address_to_pio(phys_addr_t address)
|
||||
{
|
||||
return (unsigned long)-1;
|
||||
}
|
||||
static inline int pcibios_vaddr_is_ioport(void __iomem *address)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -20,9 +20,6 @@
|
|||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
|
@ -50,29 +47,10 @@ extern void pci_create_OF_bus_map(void);
|
|||
* OF address retreival & translation
|
||||
*/
|
||||
|
||||
/* Translate an OF address block into a CPU physical address
|
||||
*/
|
||||
extern u64 of_translate_address(struct device_node *np, const u32 *addr);
|
||||
|
||||
/* Extract an address from a device, returns the region size and
|
||||
* the address space flags too. The PCI version uses a BAR number
|
||||
* instead of an absolute index
|
||||
*/
|
||||
extern const u32 *of_get_address(struct device_node *dev, int index,
|
||||
u64 *size, unsigned int *flags);
|
||||
extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
|
||||
u64 *size, unsigned int *flags);
|
||||
|
||||
/* Get an address as a resource. Note that if your address is
|
||||
* a PIO address, the conversion will fail if the physical address
|
||||
* can't be internally converted to an IO token with
|
||||
* pci_address_to_pio(), that is because it's either called to early
|
||||
* or it can't be matched to any host bridge IO space
|
||||
*/
|
||||
extern int of_address_to_resource(struct device_node *dev, int index,
|
||||
struct resource *r);
|
||||
extern int of_pci_address_to_resource(struct device_node *dev, int bar,
|
||||
struct resource *r);
|
||||
#ifdef CONFIG_PCI
|
||||
extern unsigned long pci_address_to_pio(phys_addr_t address);
|
||||
#define pci_address_to_pio pci_address_to_pio
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
/* Parse the ibm,dma-window property of an OF node into the busno, phys and
|
||||
* size parameters.
|
||||
|
@ -88,69 +66,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
|
|||
/* Get the MAC address */
|
||||
extern const void *of_get_mac_address(struct device_node *np);
|
||||
|
||||
/*
|
||||
* OF interrupt mapping
|
||||
*/
|
||||
|
||||
/* This structure is returned when an interrupt is mapped. The controller
|
||||
* field needs to be put() after use
|
||||
*/
|
||||
|
||||
#define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */
|
||||
|
||||
struct of_irq {
|
||||
struct device_node *controller; /* Interrupt controller node */
|
||||
u32 size; /* Specifier size */
|
||||
u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
|
||||
};
|
||||
|
||||
/**
|
||||
* of_irq_map_init - Initialize the irq remapper
|
||||
* @flags: flags defining workarounds to enable
|
||||
*
|
||||
* Some machines have bugs in the device-tree which require certain workarounds
|
||||
* to be applied. Call this before any interrupt mapping attempts to enable
|
||||
* those workarounds.
|
||||
*/
|
||||
#define OF_IMAP_OLDWORLD_MAC 0x00000001
|
||||
#define OF_IMAP_NO_PHANDLE 0x00000002
|
||||
|
||||
extern void of_irq_map_init(unsigned int flags);
|
||||
|
||||
/**
|
||||
* of_irq_map_raw - Low level interrupt tree parsing
|
||||
* @parent: the device interrupt parent
|
||||
* @intspec: interrupt specifier ("interrupts" property of the device)
|
||||
* @ointsize: size of the passed in interrupt specifier
|
||||
* @addr: address specifier (start of "reg" property of the device)
|
||||
* @out_irq: structure of_irq filled by this function
|
||||
*
|
||||
* Returns 0 on success and a negative number on error
|
||||
*
|
||||
* This function is a low-level interrupt tree walking function. It
|
||||
* can be used to do a partial walk with synthetized reg and interrupts
|
||||
* properties, for example when resolving PCI interrupts when no device
|
||||
* node exist for the parent.
|
||||
*
|
||||
*/
|
||||
|
||||
extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
|
||||
u32 ointsize, const u32 *addr,
|
||||
struct of_irq *out_irq);
|
||||
|
||||
/**
|
||||
* of_irq_map_one - Resolve an interrupt for a device
|
||||
* @device: the device whose interrupt is to be resolved
|
||||
* @index: index of the interrupt to resolve
|
||||
* @out_irq: structure of_irq filled by this function
|
||||
*
|
||||
* This function resolves an interrupt, walking the tree, for a given
|
||||
* device-tree node. It's the high level pendant to of_irq_map_raw().
|
||||
* It also implements the workarounds for OldWolrd Macs.
|
||||
*/
|
||||
extern int of_irq_map_one(struct device_node *device, int index,
|
||||
struct of_irq *out_irq);
|
||||
|
||||
/**
|
||||
* of_irq_map_pci - Resolve the interrupt for a PCI device
|
||||
* @pdev: the device whose interrupt is to be resolved
|
||||
|
@ -163,20 +78,18 @@ extern int of_irq_map_one(struct device_node *device, int index,
|
|||
* resolving using the OF tree walking.
|
||||
*/
|
||||
struct pci_dev;
|
||||
struct of_irq;
|
||||
extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
|
||||
|
||||
extern int of_irq_to_resource(struct device_node *dev, int index,
|
||||
struct resource *r);
|
||||
|
||||
/**
|
||||
* of_iomap - Maps the memory mapped IO for a given device_node
|
||||
* @device: the device whose io range will be mapped
|
||||
* @index: index of the io range
|
||||
*
|
||||
* Returns a pointer to the mapped memory
|
||||
*/
|
||||
extern void __iomem *of_iomap(struct device_node *device, int index);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
/* These includes are put at the bottom because they may contain things
|
||||
* that are overridden by this file. Ideally they shouldn't be included
|
||||
* by this file, but there are a bunch of .c files that currently depend
|
||||
* on it. Eventually they will be cleaned up. */
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#endif /* _ASM_MICROBLAZE_PROM_H */
|
||||
|
|
|
@ -1,11 +1 @@
|
|||
#include <asm-generic/topology.h>
|
||||
|
||||
#ifndef _ASM_MICROBLAZE_TOPOLOGY_H
|
||||
#define _ASM_MICROBLAZE_TOPOLOGY_H
|
||||
|
||||
struct device_node;
|
||||
static inline int of_node_to_nid(struct device_node *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* _ASM_MICROBLAZE_TOPOLOGY_H */
|
||||
|
|
|
@ -15,8 +15,8 @@ endif
|
|||
extra-y := head.o vmlinux.lds
|
||||
|
||||
obj-y += dma.o exceptions.o \
|
||||
hw_exception_handler.o init_task.o intc.o irq.o of_device.o \
|
||||
of_platform.o process.o prom.o prom_parse.o ptrace.o \
|
||||
hw_exception_handler.o init_task.o intc.o irq.o \
|
||||
process.o prom.o prom_parse.o ptrace.o \
|
||||
reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o
|
||||
|
||||
obj-y += cpu/
|
||||
|
|
|
@ -17,20 +17,10 @@
|
|||
#include <linux/seq_file.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#include <asm/prom.h>
|
||||
|
||||
unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
|
||||
{
|
||||
struct of_irq oirq;
|
||||
|
||||
if (of_irq_map_one(dev, index, &oirq))
|
||||
return NO_IRQ;
|
||||
|
||||
return oirq.specifier[0];
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
|
||||
|
||||
static u32 concurrent_irq;
|
||||
|
||||
void __irq_entry do_IRQ(struct pt_regs *regs)
|
||||
|
@ -106,7 +96,7 @@ unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
|
|||
EXPORT_SYMBOL_GPL(irq_create_mapping);
|
||||
|
||||
unsigned int irq_create_of_mapping(struct device_node *controller,
|
||||
u32 *intspec, unsigned int intsize)
|
||||
const u32 *intspec, unsigned int intsize)
|
||||
{
|
||||
return intspec[0];
|
||||
}
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include <linux/errno.h>
|
||||
|
||||
void of_device_make_bus_id(struct of_device *dev)
|
||||
{
|
||||
static atomic_t bus_no_reg_magic;
|
||||
struct device_node *node = dev->dev.of_node;
|
||||
const u32 *reg;
|
||||
u64 addr;
|
||||
int magic;
|
||||
|
||||
/*
|
||||
* For MMIO, get the physical address
|
||||
*/
|
||||
reg = of_get_property(node, "reg", NULL);
|
||||
if (reg) {
|
||||
addr = of_translate_address(node, reg);
|
||||
if (addr != OF_BAD_ADDR) {
|
||||
dev_set_name(&dev->dev, "%llx.%s",
|
||||
(unsigned long long)addr, node->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* No BusID, use the node name and add a globally incremented
|
||||
* counter (and pray...)
|
||||
*/
|
||||
magic = atomic_add_return(1, &bus_no_reg_magic);
|
||||
dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1);
|
||||
}
|
||||
EXPORT_SYMBOL(of_device_make_bus_id);
|
||||
|
||||
struct of_device *of_device_alloc(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent)
|
||||
{
|
||||
struct of_device *dev;
|
||||
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
dev->dev.of_node = of_node_get(np);
|
||||
dev->dev.dma_mask = &dev->archdata.dma_mask;
|
||||
dev->dev.parent = parent;
|
||||
dev->dev.release = of_release_dev;
|
||||
|
||||
if (bus_id)
|
||||
dev_set_name(&dev->dev, bus_id);
|
||||
else
|
||||
of_device_make_bus_id(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL(of_device_alloc);
|
||||
|
||||
int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct of_device *ofdev;
|
||||
const char *compat;
|
||||
int seen = 0, cplen, sl;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
ofdev = to_of_device(dev);
|
||||
|
||||
if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type))
|
||||
return -ENOMEM;
|
||||
|
||||
/* Since the compatible field can contain pretty much anything
|
||||
* it's not really legal to split it out with commas. We split it
|
||||
* up using a number of environment variables instead. */
|
||||
|
||||
compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen);
|
||||
while (compat && *compat && cplen > 0) {
|
||||
if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
|
||||
return -ENOMEM;
|
||||
|
||||
sl = strlen(compat) + 1;
|
||||
compat += sl;
|
||||
cplen -= sl;
|
||||
seen++;
|
||||
}
|
||||
|
||||
if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
|
||||
return -ENOMEM;
|
||||
|
||||
/* modalias is trickier, we add it in 2 steps */
|
||||
if (add_uevent_var(env, "MODALIAS="))
|
||||
return -ENOMEM;
|
||||
sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
|
||||
sizeof(env->buf) - env->buflen);
|
||||
if (sl >= (sizeof(env->buf) - env->buflen))
|
||||
return -ENOMEM;
|
||||
env->buflen += sl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(of_device_uevent);
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
* and Arnd Bergmann, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/topology.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
struct bus_type of_platform_bus_type = {
|
||||
.uevent = of_device_uevent,
|
||||
};
|
||||
EXPORT_SYMBOL(of_platform_bus_type);
|
||||
|
||||
static int __init of_bus_driver_init(void)
|
||||
{
|
||||
return of_bus_type_init(&of_platform_bus_type, "of_platform");
|
||||
}
|
||||
postcore_initcall(of_bus_driver_init);
|
||||
|
||||
struct of_device *of_platform_device_create(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent)
|
||||
{
|
||||
struct of_device *dev;
|
||||
|
||||
dev = of_device_alloc(np, bus_id, parent);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
dev->archdata.dma_mask = 0xffffffffUL;
|
||||
dev->dev.bus = &of_platform_bus_type;
|
||||
|
||||
/* We do not fill the DMA ops for platform devices by default.
|
||||
* This is currently the responsibility of the platform code
|
||||
* to do such, possibly using a device notifier
|
||||
*/
|
||||
|
||||
if (of_device_register(dev) != 0) {
|
||||
of_device_free(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL(of_platform_device_create);
|
||||
|
||||
/**
|
||||
* of_platform_bus_create - Create an OF device for a bus node and all its
|
||||
* children. Optionally recursively instanciate matching busses.
|
||||
* @bus: device node of the bus to instanciate
|
||||
* @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
|
||||
* disallow recursive creation of child busses
|
||||
*/
|
||||
static int of_platform_bus_create(const struct device_node *bus,
|
||||
const struct of_device_id *matches,
|
||||
struct device *parent)
|
||||
{
|
||||
struct device_node *child;
|
||||
struct of_device *dev;
|
||||
int rc = 0;
|
||||
|
||||
for_each_child_of_node(bus, child) {
|
||||
pr_debug(" create child: %s\n", child->full_name);
|
||||
dev = of_platform_device_create(child, NULL, parent);
|
||||
if (dev == NULL)
|
||||
rc = -ENOMEM;
|
||||
else if (!of_match_node(matches, child))
|
||||
continue;
|
||||
if (rc == 0) {
|
||||
pr_debug(" and sub busses\n");
|
||||
rc = of_platform_bus_create(child, matches, &dev->dev);
|
||||
}
|
||||
if (rc) {
|
||||
of_node_put(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* of_platform_bus_probe - Probe the device-tree for platform busses
|
||||
* @root: parent of the first level to probe or NULL for the root of the tree
|
||||
* @matches: match table, NULL to use the default
|
||||
* @parent: parent to hook devices from, NULL for toplevel
|
||||
*
|
||||
* Note that children of the provided root are not instanciated as devices
|
||||
* unless the specified root itself matches the bus list and is not NULL.
|
||||
*/
|
||||
|
||||
int of_platform_bus_probe(struct device_node *root,
|
||||
const struct of_device_id *matches,
|
||||
struct device *parent)
|
||||
{
|
||||
struct device_node *child;
|
||||
struct of_device *dev;
|
||||
int rc = 0;
|
||||
|
||||
if (matches == NULL)
|
||||
matches = of_default_bus_ids;
|
||||
if (matches == OF_NO_DEEP_PROBE)
|
||||
return -EINVAL;
|
||||
if (root == NULL)
|
||||
root = of_find_node_by_path("/");
|
||||
else
|
||||
of_node_get(root);
|
||||
|
||||
pr_debug("of_platform_bus_probe()\n");
|
||||
pr_debug(" starting at: %s\n", root->full_name);
|
||||
|
||||
/* Do a self check of bus type, if there's a match, create
|
||||
* children
|
||||
*/
|
||||
if (of_match_node(matches, root)) {
|
||||
pr_debug(" root match, create all sub devices\n");
|
||||
dev = of_platform_device_create(root, NULL, parent);
|
||||
if (dev == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto bail;
|
||||
}
|
||||
pr_debug(" create all sub busses\n");
|
||||
rc = of_platform_bus_create(root, matches, &dev->dev);
|
||||
goto bail;
|
||||
}
|
||||
for_each_child_of_node(root, child) {
|
||||
if (!of_match_node(matches, child))
|
||||
continue;
|
||||
|
||||
pr_debug(" match: %s\n", child->full_name);
|
||||
dev = of_platform_device_create(child, NULL, parent);
|
||||
if (dev == NULL)
|
||||
rc = -ENOMEM;
|
||||
else
|
||||
rc = of_platform_bus_create(child, matches, &dev->dev);
|
||||
if (rc) {
|
||||
of_node_put(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
bail:
|
||||
of_node_put(root);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(of_platform_bus_probe);
|
||||
|
||||
static int of_dev_node_match(struct device *dev, void *data)
|
||||
{
|
||||
return to_of_device(dev)->dev.of_node == data;
|
||||
}
|
||||
|
||||
struct of_device *of_find_device_by_node(struct device_node *np)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = bus_find_device(&of_platform_bus_type,
|
||||
NULL, np, of_dev_node_match);
|
||||
if (dev)
|
||||
return to_of_device(dev);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_device_by_node);
|
||||
|
||||
static int of_dev_phandle_match(struct device *dev, void *data)
|
||||
{
|
||||
phandle *ph = data;
|
||||
return to_of_device(dev)->dev.of_node->phandle == *ph;
|
||||
}
|
||||
|
||||
struct of_device *of_find_device_by_phandle(phandle ph)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = bus_find_device(&of_platform_bus_type,
|
||||
NULL, &ph, of_dev_phandle_match);
|
||||
if (dev)
|
||||
return to_of_device(dev);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_device_by_phandle);
|
|
@ -6,219 +6,11 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
|
||||
#define PRu64 "%llx"
|
||||
|
||||
/* Max address size we deal with */
|
||||
#define OF_MAX_ADDR_CELLS 4
|
||||
#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
|
||||
(ns) > 0)
|
||||
|
||||
static struct of_bus *of_match_bus(struct device_node *np);
|
||||
static int __of_address_to_resource(struct device_node *dev,
|
||||
const u32 *addrp, u64 size, unsigned int flags,
|
||||
struct resource *r);
|
||||
|
||||
/* Debug utility */
|
||||
#ifdef DEBUG
|
||||
static void of_dump_addr(const char *s, const u32 *addr, int na)
|
||||
{
|
||||
printk(KERN_INFO "%s", s);
|
||||
while (na--)
|
||||
printk(KERN_INFO " %08x", *(addr++));
|
||||
printk(KERN_INFO "\n");
|
||||
}
|
||||
#else
|
||||
static void of_dump_addr(const char *s, const u32 *addr, int na) { }
|
||||
#endif
|
||||
|
||||
/* Callbacks for bus specific translators */
|
||||
struct of_bus {
|
||||
const char *name;
|
||||
const char *addresses;
|
||||
int (*match)(struct device_node *parent);
|
||||
void (*count_cells)(struct device_node *child,
|
||||
int *addrc, int *sizec);
|
||||
u64 (*map)(u32 *addr, const u32 *range,
|
||||
int na, int ns, int pna);
|
||||
int (*translate)(u32 *addr, u64 offset, int na);
|
||||
unsigned int (*get_flags)(const u32 *addr);
|
||||
};
|
||||
|
||||
/*
|
||||
* Default translator (generic bus)
|
||||
*/
|
||||
|
||||
static void of_bus_default_count_cells(struct device_node *dev,
|
||||
int *addrc, int *sizec)
|
||||
{
|
||||
if (addrc)
|
||||
*addrc = of_n_addr_cells(dev);
|
||||
if (sizec)
|
||||
*sizec = of_n_size_cells(dev);
|
||||
}
|
||||
|
||||
static u64 of_bus_default_map(u32 *addr, const u32 *range,
|
||||
int na, int ns, int pna)
|
||||
{
|
||||
u64 cp, s, da;
|
||||
|
||||
cp = of_read_number(range, na);
|
||||
s = of_read_number(range + na + pna, ns);
|
||||
da = of_read_number(addr, na);
|
||||
|
||||
pr_debug("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
|
||||
cp, s, da);
|
||||
|
||||
if (da < cp || da >= (cp + s))
|
||||
return OF_BAD_ADDR;
|
||||
return da - cp;
|
||||
}
|
||||
|
||||
static int of_bus_default_translate(u32 *addr, u64 offset, int na)
|
||||
{
|
||||
u64 a = of_read_number(addr, na);
|
||||
memset(addr, 0, na * 4);
|
||||
a += offset;
|
||||
if (na > 1)
|
||||
addr[na - 2] = a >> 32;
|
||||
addr[na - 1] = a & 0xffffffffu;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int of_bus_default_get_flags(const u32 *addr)
|
||||
{
|
||||
return IORESOURCE_MEM;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/*
|
||||
* PCI bus specific translator
|
||||
*/
|
||||
|
||||
static int of_bus_pci_match(struct device_node *np)
|
||||
{
|
||||
/* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
|
||||
return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
|
||||
}
|
||||
|
||||
static void of_bus_pci_count_cells(struct device_node *np,
|
||||
int *addrc, int *sizec)
|
||||
{
|
||||
if (addrc)
|
||||
*addrc = 3;
|
||||
if (sizec)
|
||||
*sizec = 2;
|
||||
}
|
||||
|
||||
static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
|
||||
{
|
||||
u64 cp, s, da;
|
||||
|
||||
/* Check address type match */
|
||||
if ((addr[0] ^ range[0]) & 0x03000000)
|
||||
return OF_BAD_ADDR;
|
||||
|
||||
/* Read address values, skipping high cell */
|
||||
cp = of_read_number(range + 1, na - 1);
|
||||
s = of_read_number(range + na + pna, ns);
|
||||
da = of_read_number(addr + 1, na - 1);
|
||||
|
||||
pr_debug("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
|
||||
|
||||
if (da < cp || da >= (cp + s))
|
||||
return OF_BAD_ADDR;
|
||||
return da - cp;
|
||||
}
|
||||
|
||||
static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
|
||||
{
|
||||
return of_bus_default_translate(addr + 1, offset, na - 1);
|
||||
}
|
||||
|
||||
static unsigned int of_bus_pci_get_flags(const u32 *addr)
|
||||
{
|
||||
unsigned int flags = 0;
|
||||
u32 w = addr[0];
|
||||
|
||||
switch ((w >> 24) & 0x03) {
|
||||
case 0x01:
|
||||
flags |= IORESOURCE_IO;
|
||||
break;
|
||||
case 0x02: /* 32 bits */
|
||||
case 0x03: /* 64 bits */
|
||||
flags |= IORESOURCE_MEM;
|
||||
break;
|
||||
}
|
||||
if (w & 0x40000000)
|
||||
flags |= IORESOURCE_PREFETCH;
|
||||
return flags;
|
||||
}
|
||||
|
||||
const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
|
||||
unsigned int *flags)
|
||||
{
|
||||
const u32 *prop;
|
||||
unsigned int psize;
|
||||
struct device_node *parent;
|
||||
struct of_bus *bus;
|
||||
int onesize, i, na, ns;
|
||||
|
||||
/* Get parent & match bus type */
|
||||
parent = of_get_parent(dev);
|
||||
if (parent == NULL)
|
||||
return NULL;
|
||||
bus = of_match_bus(parent);
|
||||
if (strcmp(bus->name, "pci")) {
|
||||
of_node_put(parent);
|
||||
return NULL;
|
||||
}
|
||||
bus->count_cells(dev, &na, &ns);
|
||||
of_node_put(parent);
|
||||
if (!OF_CHECK_COUNTS(na, ns))
|
||||
return NULL;
|
||||
|
||||
/* Get "reg" or "assigned-addresses" property */
|
||||
prop = of_get_property(dev, bus->addresses, &psize);
|
||||
if (prop == NULL)
|
||||
return NULL;
|
||||
psize /= 4;
|
||||
|
||||
onesize = na + ns;
|
||||
for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
|
||||
if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
|
||||
if (size)
|
||||
*size = of_read_number(prop + na, ns);
|
||||
if (flags)
|
||||
*flags = bus->get_flags(prop);
|
||||
return prop;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_pci_address);
|
||||
|
||||
int of_pci_address_to_resource(struct device_node *dev, int bar,
|
||||
struct resource *r)
|
||||
{
|
||||
const u32 *addrp;
|
||||
u64 size;
|
||||
unsigned int flags;
|
||||
|
||||
addrp = of_get_pci_address(dev, bar, &size, &flags);
|
||||
if (addrp == NULL)
|
||||
return -EINVAL;
|
||||
return __of_address_to_resource(dev, addrp, size, flags, r);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
|
||||
|
||||
static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
|
||||
{
|
||||
return (((pin - 1) + slot) % 4) + 1;
|
||||
}
|
||||
|
||||
int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
|
||||
{
|
||||
struct device_node *dn, *ppnode;
|
||||
|
@ -293,331 +85,6 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
|
|||
EXPORT_SYMBOL_GPL(of_irq_map_pci);
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
/*
|
||||
* ISA bus specific translator
|
||||
*/
|
||||
|
||||
static int of_bus_isa_match(struct device_node *np)
|
||||
{
|
||||
return !strcmp(np->name, "isa");
|
||||
}
|
||||
|
||||
static void of_bus_isa_count_cells(struct device_node *child,
|
||||
int *addrc, int *sizec)
|
||||
{
|
||||
if (addrc)
|
||||
*addrc = 2;
|
||||
if (sizec)
|
||||
*sizec = 1;
|
||||
}
|
||||
|
||||
static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
|
||||
{
|
||||
u64 cp, s, da;
|
||||
|
||||
/* Check address type match */
|
||||
if ((addr[0] ^ range[0]) & 0x00000001)
|
||||
return OF_BAD_ADDR;
|
||||
|
||||
/* Read address values, skipping high cell */
|
||||
cp = of_read_number(range + 1, na - 1);
|
||||
s = of_read_number(range + na + pna, ns);
|
||||
da = of_read_number(addr + 1, na - 1);
|
||||
|
||||
pr_debug("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
|
||||
|
||||
if (da < cp || da >= (cp + s))
|
||||
return OF_BAD_ADDR;
|
||||
return da - cp;
|
||||
}
|
||||
|
||||
static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
|
||||
{
|
||||
return of_bus_default_translate(addr + 1, offset, na - 1);
|
||||
}
|
||||
|
||||
static unsigned int of_bus_isa_get_flags(const u32 *addr)
|
||||
{
|
||||
unsigned int flags = 0;
|
||||
u32 w = addr[0];
|
||||
|
||||
if (w & 1)
|
||||
flags |= IORESOURCE_IO;
|
||||
else
|
||||
flags |= IORESOURCE_MEM;
|
||||
return flags;
|
||||
}
|
||||
|
||||
/*
|
||||
* Array of bus specific translators
|
||||
*/
|
||||
|
||||
static struct of_bus of_busses[] = {
|
||||
#ifdef CONFIG_PCI
|
||||
/* PCI */
|
||||
{
|
||||
.name = "pci",
|
||||
.addresses = "assigned-addresses",
|
||||
.match = of_bus_pci_match,
|
||||
.count_cells = of_bus_pci_count_cells,
|
||||
.map = of_bus_pci_map,
|
||||
.translate = of_bus_pci_translate,
|
||||
.get_flags = of_bus_pci_get_flags,
|
||||
},
|
||||
#endif /* CONFIG_PCI */
|
||||
/* ISA */
|
||||
{
|
||||
.name = "isa",
|
||||
.addresses = "reg",
|
||||
.match = of_bus_isa_match,
|
||||
.count_cells = of_bus_isa_count_cells,
|
||||
.map = of_bus_isa_map,
|
||||
.translate = of_bus_isa_translate,
|
||||
.get_flags = of_bus_isa_get_flags,
|
||||
},
|
||||
/* Default */
|
||||
{
|
||||
.name = "default",
|
||||
.addresses = "reg",
|
||||
.match = NULL,
|
||||
.count_cells = of_bus_default_count_cells,
|
||||
.map = of_bus_default_map,
|
||||
.translate = of_bus_default_translate,
|
||||
.get_flags = of_bus_default_get_flags,
|
||||
},
|
||||
};
|
||||
|
||||
static struct of_bus *of_match_bus(struct device_node *np)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(of_busses); i++)
|
||||
if (!of_busses[i].match || of_busses[i].match(np))
|
||||
return &of_busses[i];
|
||||
BUG();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int of_translate_one(struct device_node *parent, struct of_bus *bus,
|
||||
struct of_bus *pbus, u32 *addr,
|
||||
int na, int ns, int pna)
|
||||
{
|
||||
const u32 *ranges;
|
||||
unsigned int rlen;
|
||||
int rone;
|
||||
u64 offset = OF_BAD_ADDR;
|
||||
|
||||
/* Normally, an absence of a "ranges" property means we are
|
||||
* crossing a non-translatable boundary, and thus the addresses
|
||||
* below the current not cannot be converted to CPU physical ones.
|
||||
* Unfortunately, while this is very clear in the spec, it's not
|
||||
* what Apple understood, and they do have things like /uni-n or
|
||||
* /ht nodes with no "ranges" property and a lot of perfectly
|
||||
* useable mapped devices below them. Thus we treat the absence of
|
||||
* "ranges" as equivalent to an empty "ranges" property which means
|
||||
* a 1:1 translation at that level. It's up to the caller not to try
|
||||
* to translate addresses that aren't supposed to be translated in
|
||||
* the first place. --BenH.
|
||||
*/
|
||||
ranges = of_get_property(parent, "ranges", (int *) &rlen);
|
||||
if (ranges == NULL || rlen == 0) {
|
||||
offset = of_read_number(addr, na);
|
||||
memset(addr, 0, pna * 4);
|
||||
pr_debug("OF: no ranges, 1:1 translation\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
pr_debug("OF: walking ranges...\n");
|
||||
|
||||
/* Now walk through the ranges */
|
||||
rlen /= 4;
|
||||
rone = na + pna + ns;
|
||||
for (; rlen >= rone; rlen -= rone, ranges += rone) {
|
||||
offset = bus->map(addr, ranges, na, ns, pna);
|
||||
if (offset != OF_BAD_ADDR)
|
||||
break;
|
||||
}
|
||||
if (offset == OF_BAD_ADDR) {
|
||||
pr_debug("OF: not found !\n");
|
||||
return 1;
|
||||
}
|
||||
memcpy(addr, ranges + na, 4 * pna);
|
||||
|
||||
finish:
|
||||
of_dump_addr("OF: parent translation for:", addr, pna);
|
||||
pr_debug("OF: with offset: "PRu64"\n", offset);
|
||||
|
||||
/* Translate it into parent bus space */
|
||||
return pbus->translate(addr, offset, pna);
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate an address from the device-tree into a CPU physical address,
|
||||
* this walks up the tree and applies the various bus mappings on the
|
||||
* way.
|
||||
*
|
||||
* Note: We consider that crossing any level with #size-cells == 0 to mean
|
||||
* that translation is impossible (that is we are not dealing with a value
|
||||
* that can be mapped to a cpu physical address). This is not really specified
|
||||
* that way, but this is traditionally the way IBM at least do things
|
||||
*/
|
||||
u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
|
||||
{
|
||||
struct device_node *parent = NULL;
|
||||
struct of_bus *bus, *pbus;
|
||||
u32 addr[OF_MAX_ADDR_CELLS];
|
||||
int na, ns, pna, pns;
|
||||
u64 result = OF_BAD_ADDR;
|
||||
|
||||
pr_debug("OF: ** translation for device %s **\n", dev->full_name);
|
||||
|
||||
/* Increase refcount at current level */
|
||||
of_node_get(dev);
|
||||
|
||||
/* Get parent & match bus type */
|
||||
parent = of_get_parent(dev);
|
||||
if (parent == NULL)
|
||||
goto bail;
|
||||
bus = of_match_bus(parent);
|
||||
|
||||
/* Cound address cells & copy address locally */
|
||||
bus->count_cells(dev, &na, &ns);
|
||||
if (!OF_CHECK_COUNTS(na, ns)) {
|
||||
printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
|
||||
dev->full_name);
|
||||
goto bail;
|
||||
}
|
||||
memcpy(addr, in_addr, na * 4);
|
||||
|
||||
pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n",
|
||||
bus->name, na, ns, parent->full_name);
|
||||
of_dump_addr("OF: translating address:", addr, na);
|
||||
|
||||
/* Translate */
|
||||
for (;;) {
|
||||
/* Switch to parent bus */
|
||||
of_node_put(dev);
|
||||
dev = parent;
|
||||
parent = of_get_parent(dev);
|
||||
|
||||
/* If root, we have finished */
|
||||
if (parent == NULL) {
|
||||
pr_debug("OF: reached root node\n");
|
||||
result = of_read_number(addr, na);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get new parent bus and counts */
|
||||
pbus = of_match_bus(parent);
|
||||
pbus->count_cells(dev, &pna, &pns);
|
||||
if (!OF_CHECK_COUNTS(pna, pns)) {
|
||||
printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
|
||||
dev->full_name);
|
||||
break;
|
||||
}
|
||||
|
||||
pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
|
||||
pbus->name, pna, pns, parent->full_name);
|
||||
|
||||
/* Apply bus translation */
|
||||
if (of_translate_one(dev, bus, pbus, addr, na, ns, pna))
|
||||
break;
|
||||
|
||||
/* Complete the move up one level */
|
||||
na = pna;
|
||||
ns = pns;
|
||||
bus = pbus;
|
||||
|
||||
of_dump_addr("OF: one level translation:", addr, na);
|
||||
}
|
||||
bail:
|
||||
of_node_put(parent);
|
||||
of_node_put(dev);
|
||||
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL(of_translate_address);
|
||||
|
||||
const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
|
||||
unsigned int *flags)
|
||||
{
|
||||
const u32 *prop;
|
||||
unsigned int psize;
|
||||
struct device_node *parent;
|
||||
struct of_bus *bus;
|
||||
int onesize, i, na, ns;
|
||||
|
||||
/* Get parent & match bus type */
|
||||
parent = of_get_parent(dev);
|
||||
if (parent == NULL)
|
||||
return NULL;
|
||||
bus = of_match_bus(parent);
|
||||
bus->count_cells(dev, &na, &ns);
|
||||
of_node_put(parent);
|
||||
if (!OF_CHECK_COUNTS(na, ns))
|
||||
return NULL;
|
||||
|
||||
/* Get "reg" or "assigned-addresses" property */
|
||||
prop = of_get_property(dev, bus->addresses, (int *) &psize);
|
||||
if (prop == NULL)
|
||||
return NULL;
|
||||
psize /= 4;
|
||||
|
||||
onesize = na + ns;
|
||||
for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
|
||||
if (i == index) {
|
||||
if (size)
|
||||
*size = of_read_number(prop + na, ns);
|
||||
if (flags)
|
||||
*flags = bus->get_flags(prop);
|
||||
return prop;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_address);
|
||||
|
||||
static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
|
||||
u64 size, unsigned int flags,
|
||||
struct resource *r)
|
||||
{
|
||||
u64 taddr;
|
||||
|
||||
if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
|
||||
return -EINVAL;
|
||||
taddr = of_translate_address(dev, addrp);
|
||||
if (taddr == OF_BAD_ADDR)
|
||||
return -EINVAL;
|
||||
memset(r, 0, sizeof(struct resource));
|
||||
if (flags & IORESOURCE_IO) {
|
||||
unsigned long port;
|
||||
port = -1; /* pci_address_to_pio(taddr); */
|
||||
if (port == (unsigned long)-1)
|
||||
return -EINVAL;
|
||||
r->start = port;
|
||||
r->end = port + size - 1;
|
||||
} else {
|
||||
r->start = taddr;
|
||||
r->end = taddr + size - 1;
|
||||
}
|
||||
r->flags = flags;
|
||||
r->name = dev->name;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int of_address_to_resource(struct device_node *dev, int index,
|
||||
struct resource *r)
|
||||
{
|
||||
const u32 *addrp;
|
||||
u64 size;
|
||||
unsigned int flags;
|
||||
|
||||
addrp = of_get_address(dev, index, &size, &flags);
|
||||
if (addrp == NULL)
|
||||
return -EINVAL;
|
||||
return __of_address_to_resource(dev, addrp, size, flags, r);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_address_to_resource);
|
||||
|
||||
void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
|
||||
unsigned long *busno, unsigned long *phys, unsigned long *size)
|
||||
{
|
||||
|
@ -644,308 +111,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
|
|||
*size = of_read_number(dma_window, cells);
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt remapper
|
||||
*/
|
||||
|
||||
static unsigned int of_irq_workarounds;
|
||||
static struct device_node *of_irq_dflt_pic;
|
||||
|
||||
static struct device_node *of_irq_find_parent(struct device_node *child)
|
||||
{
|
||||
struct device_node *p;
|
||||
const phandle *parp;
|
||||
|
||||
if (!of_node_get(child))
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
parp = of_get_property(child, "interrupt-parent", NULL);
|
||||
if (parp == NULL)
|
||||
p = of_get_parent(child);
|
||||
else {
|
||||
if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
|
||||
p = of_node_get(of_irq_dflt_pic);
|
||||
else
|
||||
p = of_find_node_by_phandle(*parp);
|
||||
}
|
||||
of_node_put(child);
|
||||
child = p;
|
||||
} while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* This doesn't need to be called if you don't have any special workaround
|
||||
* flags to pass
|
||||
*/
|
||||
void of_irq_map_init(unsigned int flags)
|
||||
{
|
||||
of_irq_workarounds = flags;
|
||||
|
||||
/* OldWorld, don't bother looking at other things */
|
||||
if (flags & OF_IMAP_OLDWORLD_MAC)
|
||||
return;
|
||||
|
||||
/* If we don't have phandles, let's try to locate a default interrupt
|
||||
* controller (happens when booting with BootX). We do a first match
|
||||
* here, hopefully, that only ever happens on machines with one
|
||||
* controller.
|
||||
*/
|
||||
if (flags & OF_IMAP_NO_PHANDLE) {
|
||||
struct device_node *np;
|
||||
|
||||
for (np = NULL; (np = of_find_all_nodes(np)) != NULL;) {
|
||||
if (of_get_property(np, "interrupt-controller", NULL)
|
||||
== NULL)
|
||||
continue;
|
||||
/* Skip /chosen/interrupt-controller */
|
||||
if (strcmp(np->name, "chosen") == 0)
|
||||
continue;
|
||||
/* It seems like at least one person on this planet
|
||||
* wants to use BootX on a machine with an AppleKiwi
|
||||
* controller which happens to pretend to be an
|
||||
* interrupt controller too.
|
||||
*/
|
||||
if (strcmp(np->name, "AppleKiwi") == 0)
|
||||
continue;
|
||||
/* I think we found one ! */
|
||||
of_irq_dflt_pic = np;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
|
||||
const u32 *addr, struct of_irq *out_irq)
|
||||
{
|
||||
struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
|
||||
const u32 *tmp, *imap, *imask;
|
||||
u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
|
||||
int imaplen, match, i;
|
||||
|
||||
pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],"
|
||||
"ointsize=%d\n",
|
||||
parent->full_name, intspec[0], intspec[1], ointsize);
|
||||
|
||||
ipar = of_node_get(parent);
|
||||
|
||||
/* First get the #interrupt-cells property of the current cursor
|
||||
* that tells us how to interpret the passed-in intspec. If there
|
||||
* is none, we are nice and just walk up the tree
|
||||
*/
|
||||
do {
|
||||
tmp = of_get_property(ipar, "#interrupt-cells", NULL);
|
||||
if (tmp != NULL) {
|
||||
intsize = *tmp;
|
||||
break;
|
||||
}
|
||||
tnode = ipar;
|
||||
ipar = of_irq_find_parent(ipar);
|
||||
of_node_put(tnode);
|
||||
} while (ipar);
|
||||
if (ipar == NULL) {
|
||||
pr_debug(" -> no parent found !\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pr_debug("of_irq_map_raw: ipar=%s, size=%d\n",
|
||||
ipar->full_name, intsize);
|
||||
|
||||
if (ointsize != intsize)
|
||||
return -EINVAL;
|
||||
|
||||
/* Look for this #address-cells. We have to implement the old linux
|
||||
* trick of looking for the parent here as some device-trees rely on it
|
||||
*/
|
||||
old = of_node_get(ipar);
|
||||
do {
|
||||
tmp = of_get_property(old, "#address-cells", NULL);
|
||||
tnode = of_get_parent(old);
|
||||
of_node_put(old);
|
||||
old = tnode;
|
||||
} while (old && tmp == NULL);
|
||||
of_node_put(old);
|
||||
old = NULL;
|
||||
addrsize = (tmp == NULL) ? 2 : *tmp;
|
||||
|
||||
pr_debug(" -> addrsize=%d\n", addrsize);
|
||||
|
||||
/* Now start the actual "proper" walk of the interrupt tree */
|
||||
while (ipar != NULL) {
|
||||
/* Now check if cursor is an interrupt-controller and if it is
|
||||
* then we are done
|
||||
*/
|
||||
if (of_get_property(ipar, "interrupt-controller", NULL) !=
|
||||
NULL) {
|
||||
pr_debug(" -> got it !\n");
|
||||
memcpy(out_irq->specifier, intspec,
|
||||
intsize * sizeof(u32));
|
||||
out_irq->size = intsize;
|
||||
out_irq->controller = ipar;
|
||||
of_node_put(old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Now look for an interrupt-map */
|
||||
imap = of_get_property(ipar, "interrupt-map", &imaplen);
|
||||
/* No interrupt map, check for an interrupt parent */
|
||||
if (imap == NULL) {
|
||||
pr_debug(" -> no map, getting parent\n");
|
||||
newpar = of_irq_find_parent(ipar);
|
||||
goto skiplevel;
|
||||
}
|
||||
imaplen /= sizeof(u32);
|
||||
|
||||
/* Look for a mask */
|
||||
imask = of_get_property(ipar, "interrupt-map-mask", NULL);
|
||||
|
||||
/* If we were passed no "reg" property and we attempt to parse
|
||||
* an interrupt-map, then #address-cells must be 0.
|
||||
* Fail if it's not.
|
||||
*/
|
||||
if (addr == NULL && addrsize != 0) {
|
||||
pr_debug(" -> no reg passed in when needed !\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Parse interrupt-map */
|
||||
match = 0;
|
||||
while (imaplen > (addrsize + intsize + 1) && !match) {
|
||||
/* Compare specifiers */
|
||||
match = 1;
|
||||
for (i = 0; i < addrsize && match; ++i) {
|
||||
u32 mask = imask ? imask[i] : 0xffffffffu;
|
||||
match = ((addr[i] ^ imap[i]) & mask) == 0;
|
||||
}
|
||||
for (; i < (addrsize + intsize) && match; ++i) {
|
||||
u32 mask = imask ? imask[i] : 0xffffffffu;
|
||||
match =
|
||||
((intspec[i-addrsize] ^ imap[i])
|
||||
& mask) == 0;
|
||||
}
|
||||
imap += addrsize + intsize;
|
||||
imaplen -= addrsize + intsize;
|
||||
|
||||
pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);
|
||||
|
||||
/* Get the interrupt parent */
|
||||
if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
|
||||
newpar = of_node_get(of_irq_dflt_pic);
|
||||
else
|
||||
newpar =
|
||||
of_find_node_by_phandle((phandle)*imap);
|
||||
imap++;
|
||||
--imaplen;
|
||||
|
||||
/* Check if not found */
|
||||
if (newpar == NULL) {
|
||||
pr_debug(" -> imap parent not found !\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Get #interrupt-cells and #address-cells of new
|
||||
* parent
|
||||
*/
|
||||
tmp = of_get_property(newpar, "#interrupt-cells", NULL);
|
||||
if (tmp == NULL) {
|
||||
pr_debug(" -> parent lacks "
|
||||
"#interrupt-cells!\n");
|
||||
goto fail;
|
||||
}
|
||||
newintsize = *tmp;
|
||||
tmp = of_get_property(newpar, "#address-cells", NULL);
|
||||
newaddrsize = (tmp == NULL) ? 0 : *tmp;
|
||||
|
||||
pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
|
||||
newintsize, newaddrsize);
|
||||
|
||||
/* Check for malformed properties */
|
||||
if (imaplen < (newaddrsize + newintsize))
|
||||
goto fail;
|
||||
|
||||
imap += newaddrsize + newintsize;
|
||||
imaplen -= newaddrsize + newintsize;
|
||||
|
||||
pr_debug(" -> imaplen=%d\n", imaplen);
|
||||
}
|
||||
if (!match)
|
||||
goto fail;
|
||||
|
||||
of_node_put(old);
|
||||
old = of_node_get(newpar);
|
||||
addrsize = newaddrsize;
|
||||
intsize = newintsize;
|
||||
intspec = imap - intsize;
|
||||
addr = intspec - addrsize;
|
||||
|
||||
skiplevel:
|
||||
/* Iterate again with new parent */
|
||||
pr_debug(" -> new parent: %s\n",
|
||||
newpar ? newpar->full_name : "<>");
|
||||
of_node_put(ipar);
|
||||
ipar = newpar;
|
||||
newpar = NULL;
|
||||
}
|
||||
fail:
|
||||
of_node_put(ipar);
|
||||
of_node_put(old);
|
||||
of_node_put(newpar);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_irq_map_raw);
|
||||
|
||||
int of_irq_map_one(struct device_node *device,
|
||||
int index, struct of_irq *out_irq)
|
||||
{
|
||||
struct device_node *p;
|
||||
const u32 *intspec, *tmp, *addr;
|
||||
u32 intsize, intlen;
|
||||
int res;
|
||||
|
||||
pr_debug("of_irq_map_one: dev=%s, index=%d\n",
|
||||
device->full_name, index);
|
||||
|
||||
/* Get the interrupts property */
|
||||
intspec = of_get_property(device, "interrupts", (int *) &intlen);
|
||||
if (intspec == NULL)
|
||||
return -EINVAL;
|
||||
intlen /= sizeof(u32);
|
||||
|
||||
pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen);
|
||||
|
||||
/* Get the reg property (if any) */
|
||||
addr = of_get_property(device, "reg", NULL);
|
||||
|
||||
/* Look for the interrupt parent. */
|
||||
p = of_irq_find_parent(device);
|
||||
if (p == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/* Get size of interrupt specifier */
|
||||
tmp = of_get_property(p, "#interrupt-cells", NULL);
|
||||
if (tmp == NULL) {
|
||||
of_node_put(p);
|
||||
return -EINVAL;
|
||||
}
|
||||
intsize = *tmp;
|
||||
|
||||
pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
|
||||
|
||||
/* Check index */
|
||||
if ((index + 1) * intsize > intlen)
|
||||
return -EINVAL;
|
||||
|
||||
/* Get new specifier and map it */
|
||||
res = of_irq_map_raw(p, intspec + index * intsize, intsize,
|
||||
addr, out_irq);
|
||||
of_node_put(p);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_irq_map_one);
|
||||
|
||||
/**
|
||||
* Search the device tree for the best MAC address to use. 'mac-address' is
|
||||
* checked first, because that is supposed to contain to "most recent" MAC
|
||||
|
@ -983,43 +148,3 @@ const void *of_get_mac_address(struct device_node *np)
|
|||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_mac_address);
|
||||
|
||||
int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
|
||||
{
|
||||
struct of_irq out_irq;
|
||||
int irq;
|
||||
int res;
|
||||
|
||||
res = of_irq_map_one(dev, index, &out_irq);
|
||||
|
||||
/* Get irq for the device */
|
||||
if (res) {
|
||||
pr_debug("IRQ not found... code = %d", res);
|
||||
return NO_IRQ;
|
||||
}
|
||||
/* Assuming single interrupt controller... */
|
||||
irq = out_irq.specifier[0];
|
||||
|
||||
pr_debug("IRQ found = %d", irq);
|
||||
|
||||
/* Only dereference the resource if both the
|
||||
* resource and the irq are valid. */
|
||||
if (r && irq != NO_IRQ) {
|
||||
r->start = r->end = irq;
|
||||
r->flags = IORESOURCE_IRQ;
|
||||
}
|
||||
|
||||
return irq;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_irq_to_resource);
|
||||
|
||||
void __iomem *of_iomap(struct device_node *np, int index)
|
||||
{
|
||||
struct resource res;
|
||||
|
||||
if (of_address_to_resource(np, index, &res))
|
||||
return NULL;
|
||||
|
||||
return ioremap(res.start, 1 + res.end - res.start);
|
||||
}
|
||||
EXPORT_SYMBOL(of_iomap);
|
||||
|
|
|
@ -24,8 +24,8 @@ static int of_reset_gpio_handle(void)
|
|||
int ret; /* variable which stored handle reset gpio pin */
|
||||
struct device_node *root; /* root node */
|
||||
struct device_node *gpio; /* gpio node */
|
||||
struct of_gpio_chip *of_gc = NULL;
|
||||
enum of_gpio_flags flags ;
|
||||
struct gpio_chip *gc;
|
||||
u32 flags;
|
||||
const void *gpio_spec;
|
||||
|
||||
/* find out root node */
|
||||
|
@ -39,19 +39,19 @@ static int of_reset_gpio_handle(void)
|
|||
goto err0;
|
||||
}
|
||||
|
||||
of_gc = gpio->data;
|
||||
if (!of_gc) {
|
||||
gc = of_node_to_gpiochip(gpio);
|
||||
if (!gc) {
|
||||
pr_debug("%s: gpio controller %s isn't registered\n",
|
||||
root->full_name, gpio->full_name);
|
||||
ret = -ENODEV;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
ret = of_gc->xlate(of_gc, root, gpio_spec, &flags);
|
||||
ret = gc->of_xlate(gc, root, gpio_spec, &flags);
|
||||
if (ret < 0)
|
||||
goto err1;
|
||||
|
||||
ret += of_gc->gc.base;
|
||||
ret += gc->base;
|
||||
err1:
|
||||
of_node_put(gpio);
|
||||
err0:
|
||||
|
|
|
@ -213,15 +213,9 @@ static struct notifier_block dflt_plat_bus_notifier = {
|
|||
.priority = INT_MAX,
|
||||
};
|
||||
|
||||
static struct notifier_block dflt_of_bus_notifier = {
|
||||
.notifier_call = dflt_bus_notify,
|
||||
.priority = INT_MAX,
|
||||
};
|
||||
|
||||
static int __init setup_bus_notifier(void)
|
||||
{
|
||||
bus_register_notifier(&platform_bus_type, &dflt_plat_bus_notifier);
|
||||
bus_register_notifier(&of_platform_bus_type, &dflt_of_bus_notifier);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -120,6 +120,8 @@ config ARCH_NO_VIRT_TO_BUS
|
|||
config PPC
|
||||
bool
|
||||
default y
|
||||
select OF
|
||||
select OF_FLATTREE
|
||||
select HAVE_FTRACE_MCOUNT_RECORD
|
||||
select HAVE_DYNAMIC_FTRACE
|
||||
select HAVE_FUNCTION_TRACER
|
||||
|
@ -173,10 +175,6 @@ config ARCH_MAY_HAVE_PC_FDC
|
|||
config PPC_OF
|
||||
def_bool y
|
||||
|
||||
config OF
|
||||
def_bool y
|
||||
select OF_FLATTREE
|
||||
|
||||
config PPC_UDBG_16550
|
||||
bool
|
||||
default n
|
||||
|
@ -199,10 +197,6 @@ config SYS_SUPPORTS_APM_EMULATION
|
|||
default y if PMAC_APM_EMU
|
||||
bool
|
||||
|
||||
config DTC
|
||||
bool
|
||||
default y
|
||||
|
||||
config DEFAULT_UIMAGE
|
||||
bool
|
||||
help
|
||||
|
@ -579,14 +573,6 @@ config SCHED_SMT
|
|||
when dealing with POWER5 cpus at a cost of slightly increased
|
||||
overhead in some places. If unsure say N here.
|
||||
|
||||
config PROC_DEVICETREE
|
||||
bool "Support for device tree in /proc"
|
||||
depends on PROC_FS
|
||||
help
|
||||
This option adds a device-tree directory under /proc which contains
|
||||
an image of the device tree that the kernel copies from Open
|
||||
Firmware or other boot firmware. If unsure, say Y here.
|
||||
|
||||
config CMDLINE_BOOL
|
||||
bool "Default bootloader kernel arguments"
|
||||
|
||||
|
|
|
@ -300,34 +300,6 @@ extern unsigned int irq_alloc_virt(struct irq_host *host,
|
|||
*/
|
||||
extern void irq_free_virt(unsigned int virq, unsigned int count);
|
||||
|
||||
|
||||
/* -- OF helpers -- */
|
||||
|
||||
/**
|
||||
* irq_create_of_mapping - Map a hardware interrupt into linux virq space
|
||||
* @controller: Device node of the interrupt controller
|
||||
* @inspec: Interrupt specifier from the device-tree
|
||||
* @intsize: Size of the interrupt specifier from the device-tree
|
||||
*
|
||||
* This function is identical to irq_create_mapping except that it takes
|
||||
* as input informations straight from the device-tree (typically the results
|
||||
* of the of_irq_map_*() functions.
|
||||
*/
|
||||
extern unsigned int irq_create_of_mapping(struct device_node *controller,
|
||||
const u32 *intspec, unsigned int intsize);
|
||||
|
||||
/**
|
||||
* irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
|
||||
* @device: Device node of the device whose interrupt is to be mapped
|
||||
* @index: Index of the interrupt to map
|
||||
*
|
||||
* This function is a wrapper that chains of_irq_map_one() and
|
||||
* irq_create_of_mapping() to make things easier to callers
|
||||
*/
|
||||
extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index);
|
||||
|
||||
/* -- End OF helpers -- */
|
||||
|
||||
/**
|
||||
* irq_early_init - Init irq remapping subsystem
|
||||
*/
|
||||
|
|
|
@ -38,7 +38,7 @@ struct macio_dev
|
|||
{
|
||||
struct macio_bus *bus; /* macio bus this device is on */
|
||||
struct macio_dev *media_bay; /* Device is part of a media bay */
|
||||
struct of_device ofdev;
|
||||
struct platform_device ofdev;
|
||||
struct device_dma_parameters dma_parms; /* ide needs that */
|
||||
int n_resources;
|
||||
struct resource resource[MACIO_DEV_COUNT_RESOURCES];
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
#ifndef _ASM_POWERPC_OF_DEVICE_H
|
||||
#define _ASM_POWERPC_OF_DEVICE_H
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
/*
|
||||
* The of_device is a kind of "base class" that is a superset of
|
||||
* struct device for use by devices attached to an OF node and
|
||||
* probed using OF properties.
|
||||
*/
|
||||
struct of_device
|
||||
{
|
||||
struct device dev; /* Generic device interface */
|
||||
struct pdev_archdata archdata;
|
||||
};
|
||||
|
||||
extern struct of_device *of_device_alloc(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent);
|
||||
|
||||
extern int of_device_uevent(struct device *dev,
|
||||
struct kobj_uevent_env *env);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_POWERPC_OF_DEVICE_H */
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef _ASM_POWERPC_OF_PLATFORM_H
|
||||
#define _ASM_POWERPC_OF_PLATFORM_H
|
||||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Platform devices and busses creation */
|
||||
extern struct of_device *of_platform_device_create(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent);
|
||||
/* pseudo "matches" value to not do deep probe */
|
||||
#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
|
||||
|
||||
extern int of_platform_bus_probe(struct device_node *root,
|
||||
const struct of_device_id *matches,
|
||||
struct device *parent);
|
||||
|
||||
extern struct of_device *of_find_device_by_phandle(phandle ph);
|
||||
|
||||
extern void of_instantiate_rtc(void);
|
||||
|
||||
#endif /* _ASM_POWERPC_OF_PLATFORM_H */
|
|
@ -303,13 +303,8 @@ extern void pcibios_free_controller(struct pci_controller *phb);
|
|||
extern void pcibios_setup_phb_resources(struct pci_controller *hose);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
extern unsigned long pci_address_to_pio(phys_addr_t address);
|
||||
extern int pcibios_vaddr_is_ioport(void __iomem *address);
|
||||
#else
|
||||
static inline unsigned long pci_address_to_pio(phys_addr_t address)
|
||||
{
|
||||
return (unsigned long)-1;
|
||||
}
|
||||
static inline int pcibios_vaddr_is_ioport(void __iomem *address)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -17,9 +17,6 @@
|
|||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
|
@ -43,49 +40,14 @@ extern void pci_create_OF_bus_map(void);
|
|||
* OF address retreival & translation
|
||||
*/
|
||||
|
||||
/* Translate an OF address block into a CPU physical address
|
||||
*/
|
||||
extern u64 of_translate_address(struct device_node *np, const u32 *addr);
|
||||
|
||||
/* Translate a DMA address from device space to CPU space */
|
||||
extern u64 of_translate_dma_address(struct device_node *dev,
|
||||
const u32 *in_addr);
|
||||
|
||||
/* Extract an address from a device, returns the region size and
|
||||
* the address space flags too. The PCI version uses a BAR number
|
||||
* instead of an absolute index
|
||||
*/
|
||||
extern const u32 *of_get_address(struct device_node *dev, int index,
|
||||
u64 *size, unsigned int *flags);
|
||||
#ifdef CONFIG_PCI
|
||||
extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no,
|
||||
u64 *size, unsigned int *flags);
|
||||
#else
|
||||
static inline const u32 *of_get_pci_address(struct device_node *dev,
|
||||
int bar_no, u64 *size, unsigned int *flags)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
/* Get an address as a resource. Note that if your address is
|
||||
* a PIO address, the conversion will fail if the physical address
|
||||
* can't be internally converted to an IO token with
|
||||
* pci_address_to_pio(), that is because it's either called to early
|
||||
* or it can't be matched to any host bridge IO space
|
||||
*/
|
||||
extern int of_address_to_resource(struct device_node *dev, int index,
|
||||
struct resource *r);
|
||||
#ifdef CONFIG_PCI
|
||||
extern int of_pci_address_to_resource(struct device_node *dev, int bar,
|
||||
struct resource *r);
|
||||
#else
|
||||
static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
|
||||
struct resource *r)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
extern unsigned long pci_address_to_pio(phys_addr_t address);
|
||||
#define pci_address_to_pio pci_address_to_pio
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
/* Parse the ibm,dma-window property of an OF node into the busno, phys and
|
||||
* size parameters.
|
||||
|
@ -104,69 +66,12 @@ struct device_node *of_find_next_cache_node(struct device_node *np);
|
|||
/* Get the MAC address */
|
||||
extern const void *of_get_mac_address(struct device_node *np);
|
||||
|
||||
/*
|
||||
* OF interrupt mapping
|
||||
*/
|
||||
|
||||
/* This structure is returned when an interrupt is mapped. The controller
|
||||
* field needs to be put() after use
|
||||
*/
|
||||
|
||||
#define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */
|
||||
|
||||
struct of_irq {
|
||||
struct device_node *controller; /* Interrupt controller node */
|
||||
u32 size; /* Specifier size */
|
||||
u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
|
||||
};
|
||||
|
||||
/**
|
||||
* of_irq_map_init - Initialize the irq remapper
|
||||
* @flags: flags defining workarounds to enable
|
||||
*
|
||||
* Some machines have bugs in the device-tree which require certain workarounds
|
||||
* to be applied. Call this before any interrupt mapping attempts to enable
|
||||
* those workarounds.
|
||||
*/
|
||||
#define OF_IMAP_OLDWORLD_MAC 0x00000001
|
||||
#define OF_IMAP_NO_PHANDLE 0x00000002
|
||||
|
||||
extern void of_irq_map_init(unsigned int flags);
|
||||
|
||||
/**
|
||||
* of_irq_map_raw - Low level interrupt tree parsing
|
||||
* @parent: the device interrupt parent
|
||||
* @intspec: interrupt specifier ("interrupts" property of the device)
|
||||
* @ointsize: size of the passed in interrupt specifier
|
||||
* @addr: address specifier (start of "reg" property of the device)
|
||||
* @out_irq: structure of_irq filled by this function
|
||||
*
|
||||
* Returns 0 on success and a negative number on error
|
||||
*
|
||||
* This function is a low-level interrupt tree walking function. It
|
||||
* can be used to do a partial walk with synthetized reg and interrupts
|
||||
* properties, for example when resolving PCI interrupts when no device
|
||||
* node exist for the parent.
|
||||
*
|
||||
*/
|
||||
|
||||
extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec,
|
||||
u32 ointsize, const u32 *addr,
|
||||
struct of_irq *out_irq);
|
||||
|
||||
|
||||
/**
|
||||
* of_irq_map_one - Resolve an interrupt for a device
|
||||
* @device: the device whose interrupt is to be resolved
|
||||
* @index: index of the interrupt to resolve
|
||||
* @out_irq: structure of_irq filled by this function
|
||||
*
|
||||
* This function resolves an interrupt, walking the tree, for a given
|
||||
* device-tree node. It's the high level pendant to of_irq_map_raw().
|
||||
* It also implements the workarounds for OldWolrd Macs.
|
||||
*/
|
||||
extern int of_irq_map_one(struct device_node *device, int index,
|
||||
struct of_irq *out_irq);
|
||||
#ifdef CONFIG_NUMA
|
||||
extern int of_node_to_nid(struct device_node *device);
|
||||
#else
|
||||
static inline int of_node_to_nid(struct device_node *device) { return 0; }
|
||||
#endif
|
||||
#define of_node_to_nid of_node_to_nid
|
||||
|
||||
/**
|
||||
* of_irq_map_pci - Resolve the interrupt for a PCI device
|
||||
|
@ -180,19 +85,19 @@ extern int of_irq_map_one(struct device_node *device, int index,
|
|||
* resolving using the OF tree walking.
|
||||
*/
|
||||
struct pci_dev;
|
||||
struct of_irq;
|
||||
extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
|
||||
|
||||
extern int of_irq_to_resource(struct device_node *dev, int index,
|
||||
struct resource *r);
|
||||
extern void of_instantiate_rtc(void);
|
||||
|
||||
/**
|
||||
* of_iomap - Maps the memory mapped IO for a given device_node
|
||||
* @device: the device whose io range will be mapped
|
||||
* @index: index of the io range
|
||||
*
|
||||
* Returns a pointer to the mapped memory
|
||||
*/
|
||||
extern void __iomem *of_iomap(struct device_node *device, int index);
|
||||
/* These includes are put at the bottom because they may contain things
|
||||
* that are overridden by this file. Ideally they shouldn't be included
|
||||
* by this file, but there are a bunch of .c files that currently depend
|
||||
* on it. Eventually they will be cleaned up. */
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _POWERPC_PROM_H */
|
||||
|
|
|
@ -457,8 +457,8 @@ extern void smu_poll(void);
|
|||
*/
|
||||
extern int smu_init(void);
|
||||
extern int smu_present(void);
|
||||
struct of_device;
|
||||
extern struct of_device *smu_get_ofdev(void);
|
||||
struct platform_device;
|
||||
extern struct platform_device *smu_get_ofdev(void);
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -41,8 +41,6 @@ static inline int cpu_to_node(int cpu)
|
|||
cpu_all_mask : \
|
||||
node_to_cpumask_map[node])
|
||||
|
||||
int of_node_to_nid(struct device_node *device);
|
||||
|
||||
struct pci_bus;
|
||||
#ifdef CONFIG_PCI
|
||||
extern int pcibus_to_node(struct pci_bus *bus);
|
||||
|
@ -97,11 +95,6 @@ extern void sysfs_remove_device_from_node(struct sys_device *dev, int nid);
|
|||
|
||||
#else
|
||||
|
||||
static inline int of_node_to_nid(struct device_node *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void dump_numa_cpu_topology(void) {}
|
||||
|
||||
static inline int sysfs_add_device_to_node(struct sys_device *dev, int nid)
|
||||
|
|
|
@ -41,7 +41,7 @@ obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o
|
|||
obj-$(CONFIG_PPC64) += vdso64/
|
||||
obj-$(CONFIG_ALTIVEC) += vecemu.o
|
||||
obj-$(CONFIG_PPC_970_NAP) += idle_power4.o
|
||||
obj-$(CONFIG_PPC_OF) += of_device.o of_platform.o prom_parse.o
|
||||
obj-$(CONFIG_PPC_OF) += of_platform.o prom_parse.o
|
||||
obj-$(CONFIG_PPC_CLOCK) += clock.o
|
||||
procfs-y := proc_powerpc.o
|
||||
obj-$(CONFIG_PROC_FS) += $(procfs-y)
|
||||
|
|
|
@ -82,17 +82,9 @@ static struct notifier_block ppc_swiotlb_plat_bus_notifier = {
|
|||
.priority = 0,
|
||||
};
|
||||
|
||||
static struct notifier_block ppc_swiotlb_of_bus_notifier = {
|
||||
.notifier_call = ppc_swiotlb_bus_notify,
|
||||
.priority = 0,
|
||||
};
|
||||
|
||||
int __init swiotlb_setup_bus_notifier(void)
|
||||
{
|
||||
bus_register_notifier(&platform_bus_type,
|
||||
&ppc_swiotlb_plat_bus_notifier);
|
||||
bus_register_notifier(&of_platform_bus_type,
|
||||
&ppc_swiotlb_of_bus_notifier);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -140,19 +140,19 @@ static struct dma_map_ops ibmebus_dma_ops = {
|
|||
|
||||
static int ibmebus_match_path(struct device *dev, void *data)
|
||||
{
|
||||
struct device_node *dn = to_of_device(dev)->dev.of_node;
|
||||
struct device_node *dn = to_platform_device(dev)->dev.of_node;
|
||||
return (dn->full_name &&
|
||||
(strcasecmp((char *)data, dn->full_name) == 0));
|
||||
}
|
||||
|
||||
static int ibmebus_match_node(struct device *dev, void *data)
|
||||
{
|
||||
return to_of_device(dev)->dev.of_node == data;
|
||||
return to_platform_device(dev)->dev.of_node == data;
|
||||
}
|
||||
|
||||
static int ibmebus_create_device(struct device_node *dn)
|
||||
{
|
||||
struct of_device *dev;
|
||||
struct platform_device *dev;
|
||||
int ret;
|
||||
|
||||
dev = of_device_alloc(dn, NULL, &ibmebus_bus_device);
|
||||
|
@ -298,7 +298,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus,
|
|||
|
||||
if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path,
|
||||
ibmebus_match_path))) {
|
||||
of_device_unregister(to_of_device(dev));
|
||||
of_device_unregister(to_platform_device(dev));
|
||||
|
||||
kfree(path);
|
||||
return count;
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
#include <linux/bootmem.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/system.h>
|
||||
|
@ -820,18 +822,6 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(irq_create_of_mapping);
|
||||
|
||||
unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
|
||||
{
|
||||
struct of_irq oirq;
|
||||
|
||||
if (of_irq_map_one(dev, index, &oirq))
|
||||
return NO_IRQ;
|
||||
|
||||
return irq_create_of_mapping(oirq.controller, oirq.specifier,
|
||||
oirq.size);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
|
||||
|
||||
void irq_dispose_mapping(unsigned int virq)
|
||||
{
|
||||
struct irq_host *host;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <linux/serial_core.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mmu.h>
|
||||
|
|
|
@ -1,133 +0,0 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include <asm/errno.h>
|
||||
#include <asm/dcr.h>
|
||||
|
||||
static void of_device_make_bus_id(struct of_device *dev)
|
||||
{
|
||||
static atomic_t bus_no_reg_magic;
|
||||
struct device_node *node = dev->dev.of_node;
|
||||
const u32 *reg;
|
||||
u64 addr;
|
||||
int magic;
|
||||
|
||||
/*
|
||||
* If it's a DCR based device, use 'd' for native DCRs
|
||||
* and 'D' for MMIO DCRs.
|
||||
*/
|
||||
#ifdef CONFIG_PPC_DCR
|
||||
reg = of_get_property(node, "dcr-reg", NULL);
|
||||
if (reg) {
|
||||
#ifdef CONFIG_PPC_DCR_NATIVE
|
||||
dev_set_name(&dev->dev, "d%x.%s", *reg, node->name);
|
||||
#else /* CONFIG_PPC_DCR_NATIVE */
|
||||
addr = of_translate_dcr_address(node, *reg, NULL);
|
||||
if (addr != OF_BAD_ADDR) {
|
||||
dev_set_name(&dev->dev, "D%llx.%s",
|
||||
(unsigned long long)addr, node->name);
|
||||
return;
|
||||
}
|
||||
#endif /* !CONFIG_PPC_DCR_NATIVE */
|
||||
}
|
||||
#endif /* CONFIG_PPC_DCR */
|
||||
|
||||
/*
|
||||
* For MMIO, get the physical address
|
||||
*/
|
||||
reg = of_get_property(node, "reg", NULL);
|
||||
if (reg) {
|
||||
addr = of_translate_address(node, reg);
|
||||
if (addr != OF_BAD_ADDR) {
|
||||
dev_set_name(&dev->dev, "%llx.%s",
|
||||
(unsigned long long)addr, node->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* No BusID, use the node name and add a globally incremented
|
||||
* counter (and pray...)
|
||||
*/
|
||||
magic = atomic_add_return(1, &bus_no_reg_magic);
|
||||
dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1);
|
||||
}
|
||||
|
||||
struct of_device *of_device_alloc(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent)
|
||||
{
|
||||
struct of_device *dev;
|
||||
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
dev->dev.of_node = of_node_get(np);
|
||||
dev->dev.dma_mask = &dev->archdata.dma_mask;
|
||||
dev->dev.parent = parent;
|
||||
dev->dev.release = of_release_dev;
|
||||
|
||||
if (bus_id)
|
||||
dev_set_name(&dev->dev, "%s", bus_id);
|
||||
else
|
||||
of_device_make_bus_id(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL(of_device_alloc);
|
||||
|
||||
int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
struct of_device *ofdev;
|
||||
const char *compat;
|
||||
int seen = 0, cplen, sl;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
ofdev = to_of_device(dev);
|
||||
|
||||
if (add_uevent_var(env, "OF_NAME=%s", ofdev->dev.of_node->name))
|
||||
return -ENOMEM;
|
||||
|
||||
if (add_uevent_var(env, "OF_TYPE=%s", ofdev->dev.of_node->type))
|
||||
return -ENOMEM;
|
||||
|
||||
/* Since the compatible field can contain pretty much anything
|
||||
* it's not really legal to split it out with commas. We split it
|
||||
* up using a number of environment variables instead. */
|
||||
|
||||
compat = of_get_property(ofdev->dev.of_node, "compatible", &cplen);
|
||||
while (compat && *compat && cplen > 0) {
|
||||
if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
|
||||
return -ENOMEM;
|
||||
|
||||
sl = strlen (compat) + 1;
|
||||
compat += sl;
|
||||
cplen -= sl;
|
||||
seen++;
|
||||
}
|
||||
|
||||
if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
|
||||
return -ENOMEM;
|
||||
|
||||
/* modalias is trickier, we add it in 2 steps */
|
||||
if (add_uevent_var(env, "MODALIAS="))
|
||||
return -ENOMEM;
|
||||
sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
|
||||
sizeof(env->buf) - env->buflen);
|
||||
if (sl >= (sizeof(env->buf) - env->buflen))
|
||||
return -ENOMEM;
|
||||
env->buflen += sl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(of_device_uevent);
|
||||
EXPORT_SYMBOL(of_device_get_modalias);
|
|
@ -28,207 +28,6 @@
|
|||
#include <asm/ppc-pci.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
/*
|
||||
* The list of OF IDs below is used for matching bus types in the
|
||||
* system whose devices are to be exposed as of_platform_devices.
|
||||
*
|
||||
* This is the default list valid for most platforms. This file provides
|
||||
* functions who can take an explicit list if necessary though
|
||||
*
|
||||
* The search is always performed recursively looking for children of
|
||||
* the provided device_node and recursively if such a children matches
|
||||
* a bus type in the list
|
||||
*/
|
||||
|
||||
static const struct of_device_id of_default_bus_ids[] = {
|
||||
{ .type = "soc", },
|
||||
{ .compatible = "soc", },
|
||||
{ .type = "spider", },
|
||||
{ .type = "axon", },
|
||||
{ .type = "plb5", },
|
||||
{ .type = "plb4", },
|
||||
{ .type = "opb", },
|
||||
{ .type = "ebc", },
|
||||
{},
|
||||
};
|
||||
|
||||
struct bus_type of_platform_bus_type = {
|
||||
.uevent = of_device_uevent,
|
||||
};
|
||||
EXPORT_SYMBOL(of_platform_bus_type);
|
||||
|
||||
static int __init of_bus_driver_init(void)
|
||||
{
|
||||
return of_bus_type_init(&of_platform_bus_type, "of_platform");
|
||||
}
|
||||
|
||||
postcore_initcall(of_bus_driver_init);
|
||||
|
||||
struct of_device* of_platform_device_create(struct device_node *np,
|
||||
const char *bus_id,
|
||||
struct device *parent)
|
||||
{
|
||||
struct of_device *dev;
|
||||
|
||||
dev = of_device_alloc(np, bus_id, parent);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
dev->archdata.dma_mask = 0xffffffffUL;
|
||||
dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
dev->dev.bus = &of_platform_bus_type;
|
||||
|
||||
/* We do not fill the DMA ops for platform devices by default.
|
||||
* This is currently the responsibility of the platform code
|
||||
* to do such, possibly using a device notifier
|
||||
*/
|
||||
|
||||
if (of_device_register(dev) != 0) {
|
||||
of_device_free(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL(of_platform_device_create);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* of_platform_bus_create - Create an OF device for a bus node and all its
|
||||
* children. Optionally recursively instanciate matching busses.
|
||||
* @bus: device node of the bus to instanciate
|
||||
* @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
|
||||
* disallow recursive creation of child busses
|
||||
*/
|
||||
static int of_platform_bus_create(const struct device_node *bus,
|
||||
const struct of_device_id *matches,
|
||||
struct device *parent)
|
||||
{
|
||||
struct device_node *child;
|
||||
struct of_device *dev;
|
||||
int rc = 0;
|
||||
|
||||
for_each_child_of_node(bus, child) {
|
||||
pr_debug(" create child: %s\n", child->full_name);
|
||||
dev = of_platform_device_create(child, NULL, parent);
|
||||
if (dev == NULL)
|
||||
rc = -ENOMEM;
|
||||
else if (!of_match_node(matches, child))
|
||||
continue;
|
||||
if (rc == 0) {
|
||||
pr_debug(" and sub busses\n");
|
||||
rc = of_platform_bus_create(child, matches, &dev->dev);
|
||||
} if (rc) {
|
||||
of_node_put(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_platform_bus_probe - Probe the device-tree for platform busses
|
||||
* @root: parent of the first level to probe or NULL for the root of the tree
|
||||
* @matches: match table, NULL to use the default
|
||||
* @parent: parent to hook devices from, NULL for toplevel
|
||||
*
|
||||
* Note that children of the provided root are not instanciated as devices
|
||||
* unless the specified root itself matches the bus list and is not NULL.
|
||||
*/
|
||||
|
||||
int of_platform_bus_probe(struct device_node *root,
|
||||
const struct of_device_id *matches,
|
||||
struct device *parent)
|
||||
{
|
||||
struct device_node *child;
|
||||
struct of_device *dev;
|
||||
int rc = 0;
|
||||
|
||||
if (matches == NULL)
|
||||
matches = of_default_bus_ids;
|
||||
if (matches == OF_NO_DEEP_PROBE)
|
||||
return -EINVAL;
|
||||
if (root == NULL)
|
||||
root = of_find_node_by_path("/");
|
||||
else
|
||||
of_node_get(root);
|
||||
|
||||
pr_debug("of_platform_bus_probe()\n");
|
||||
pr_debug(" starting at: %s\n", root->full_name);
|
||||
|
||||
/* Do a self check of bus type, if there's a match, create
|
||||
* children
|
||||
*/
|
||||
if (of_match_node(matches, root)) {
|
||||
pr_debug(" root match, create all sub devices\n");
|
||||
dev = of_platform_device_create(root, NULL, parent);
|
||||
if (dev == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto bail;
|
||||
}
|
||||
pr_debug(" create all sub busses\n");
|
||||
rc = of_platform_bus_create(root, matches, &dev->dev);
|
||||
goto bail;
|
||||
}
|
||||
for_each_child_of_node(root, child) {
|
||||
if (!of_match_node(matches, child))
|
||||
continue;
|
||||
|
||||
pr_debug(" match: %s\n", child->full_name);
|
||||
dev = of_platform_device_create(child, NULL, parent);
|
||||
if (dev == NULL)
|
||||
rc = -ENOMEM;
|
||||
else
|
||||
rc = of_platform_bus_create(child, matches, &dev->dev);
|
||||
if (rc) {
|
||||
of_node_put(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
bail:
|
||||
of_node_put(root);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(of_platform_bus_probe);
|
||||
|
||||
static int of_dev_node_match(struct device *dev, void *data)
|
||||
{
|
||||
return to_of_device(dev)->dev.of_node == data;
|
||||
}
|
||||
|
||||
struct of_device *of_find_device_by_node(struct device_node *np)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = bus_find_device(&of_platform_bus_type,
|
||||
NULL, np, of_dev_node_match);
|
||||
if (dev)
|
||||
return to_of_device(dev);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_device_by_node);
|
||||
|
||||
static int of_dev_phandle_match(struct device *dev, void *data)
|
||||
{
|
||||
phandle *ph = data;
|
||||
return to_of_device(dev)->dev.of_node->phandle == *ph;
|
||||
}
|
||||
|
||||
struct of_device *of_find_device_by_phandle(phandle ph)
|
||||
{
|
||||
struct device *dev;
|
||||
|
||||
dev = bus_find_device(&of_platform_bus_type,
|
||||
NULL, &ph, of_dev_phandle_match);
|
||||
if (dev)
|
||||
return to_of_device(dev);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_device_by_phandle);
|
||||
|
||||
|
||||
#ifdef CONFIG_PPC_OF_PLATFORM_PCI
|
||||
|
||||
/* The probing of PCI controllers from of_platform is currently
|
||||
|
@ -237,7 +36,7 @@ EXPORT_SYMBOL(of_find_device_by_phandle);
|
|||
* lacking some bits needed here.
|
||||
*/
|
||||
|
||||
static int __devinit of_pci_phb_probe(struct of_device *dev,
|
||||
static int __devinit of_pci_phb_probe(struct platform_device *dev,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct pci_controller *phb;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/string.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/syscalls.h>
|
||||
|
|
|
@ -6,232 +6,11 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG(fmt...) do { printk(fmt); } while(0)
|
||||
#else
|
||||
#define DBG(fmt...) do { } while(0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
#define PRu64 "%lx"
|
||||
#else
|
||||
#define PRu64 "%llx"
|
||||
#endif
|
||||
|
||||
/* Max address size we deal with */
|
||||
#define OF_MAX_ADDR_CELLS 4
|
||||
#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
|
||||
(ns) > 0)
|
||||
|
||||
static struct of_bus *of_match_bus(struct device_node *np);
|
||||
static int __of_address_to_resource(struct device_node *dev,
|
||||
const u32 *addrp, u64 size, unsigned int flags,
|
||||
struct resource *r);
|
||||
|
||||
|
||||
/* Debug utility */
|
||||
#ifdef DEBUG
|
||||
static void of_dump_addr(const char *s, const u32 *addr, int na)
|
||||
{
|
||||
printk("%s", s);
|
||||
while(na--)
|
||||
printk(" %08x", *(addr++));
|
||||
printk("\n");
|
||||
}
|
||||
#else
|
||||
static void of_dump_addr(const char *s, const u32 *addr, int na) { }
|
||||
#endif
|
||||
|
||||
|
||||
/* Callbacks for bus specific translators */
|
||||
struct of_bus {
|
||||
const char *name;
|
||||
const char *addresses;
|
||||
int (*match)(struct device_node *parent);
|
||||
void (*count_cells)(struct device_node *child,
|
||||
int *addrc, int *sizec);
|
||||
u64 (*map)(u32 *addr, const u32 *range,
|
||||
int na, int ns, int pna);
|
||||
int (*translate)(u32 *addr, u64 offset, int na);
|
||||
unsigned int (*get_flags)(const u32 *addr);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Default translator (generic bus)
|
||||
*/
|
||||
|
||||
static void of_bus_default_count_cells(struct device_node *dev,
|
||||
int *addrc, int *sizec)
|
||||
{
|
||||
if (addrc)
|
||||
*addrc = of_n_addr_cells(dev);
|
||||
if (sizec)
|
||||
*sizec = of_n_size_cells(dev);
|
||||
}
|
||||
|
||||
static u64 of_bus_default_map(u32 *addr, const u32 *range,
|
||||
int na, int ns, int pna)
|
||||
{
|
||||
u64 cp, s, da;
|
||||
|
||||
cp = of_read_number(range, na);
|
||||
s = of_read_number(range + na + pna, ns);
|
||||
da = of_read_number(addr, na);
|
||||
|
||||
DBG("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n",
|
||||
cp, s, da);
|
||||
|
||||
if (da < cp || da >= (cp + s))
|
||||
return OF_BAD_ADDR;
|
||||
return da - cp;
|
||||
}
|
||||
|
||||
static int of_bus_default_translate(u32 *addr, u64 offset, int na)
|
||||
{
|
||||
u64 a = of_read_number(addr, na);
|
||||
memset(addr, 0, na * 4);
|
||||
a += offset;
|
||||
if (na > 1)
|
||||
addr[na - 2] = a >> 32;
|
||||
addr[na - 1] = a & 0xffffffffu;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int of_bus_default_get_flags(const u32 *addr)
|
||||
{
|
||||
return IORESOURCE_MEM;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/*
|
||||
* PCI bus specific translator
|
||||
*/
|
||||
|
||||
static int of_bus_pci_match(struct device_node *np)
|
||||
{
|
||||
/* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
|
||||
return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
|
||||
}
|
||||
|
||||
static void of_bus_pci_count_cells(struct device_node *np,
|
||||
int *addrc, int *sizec)
|
||||
{
|
||||
if (addrc)
|
||||
*addrc = 3;
|
||||
if (sizec)
|
||||
*sizec = 2;
|
||||
}
|
||||
|
||||
static unsigned int of_bus_pci_get_flags(const u32 *addr)
|
||||
{
|
||||
unsigned int flags = 0;
|
||||
u32 w = addr[0];
|
||||
|
||||
switch((w >> 24) & 0x03) {
|
||||
case 0x01:
|
||||
flags |= IORESOURCE_IO;
|
||||
break;
|
||||
case 0x02: /* 32 bits */
|
||||
case 0x03: /* 64 bits */
|
||||
flags |= IORESOURCE_MEM;
|
||||
break;
|
||||
}
|
||||
if (w & 0x40000000)
|
||||
flags |= IORESOURCE_PREFETCH;
|
||||
return flags;
|
||||
}
|
||||
|
||||
static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
|
||||
{
|
||||
u64 cp, s, da;
|
||||
unsigned int af, rf;
|
||||
|
||||
af = of_bus_pci_get_flags(addr);
|
||||
rf = of_bus_pci_get_flags(range);
|
||||
|
||||
/* Check address type match */
|
||||
if ((af ^ rf) & (IORESOURCE_MEM | IORESOURCE_IO))
|
||||
return OF_BAD_ADDR;
|
||||
|
||||
/* Read address values, skipping high cell */
|
||||
cp = of_read_number(range + 1, na - 1);
|
||||
s = of_read_number(range + na + pna, ns);
|
||||
da = of_read_number(addr + 1, na - 1);
|
||||
|
||||
DBG("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
|
||||
|
||||
if (da < cp || da >= (cp + s))
|
||||
return OF_BAD_ADDR;
|
||||
return da - cp;
|
||||
}
|
||||
|
||||
static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
|
||||
{
|
||||
return of_bus_default_translate(addr + 1, offset, na - 1);
|
||||
}
|
||||
|
||||
const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
|
||||
unsigned int *flags)
|
||||
{
|
||||
const u32 *prop;
|
||||
unsigned int psize;
|
||||
struct device_node *parent;
|
||||
struct of_bus *bus;
|
||||
int onesize, i, na, ns;
|
||||
|
||||
/* Get parent & match bus type */
|
||||
parent = of_get_parent(dev);
|
||||
if (parent == NULL)
|
||||
return NULL;
|
||||
bus = of_match_bus(parent);
|
||||
if (strcmp(bus->name, "pci")) {
|
||||
of_node_put(parent);
|
||||
return NULL;
|
||||
}
|
||||
bus->count_cells(dev, &na, &ns);
|
||||
of_node_put(parent);
|
||||
if (!OF_CHECK_COUNTS(na, ns))
|
||||
return NULL;
|
||||
|
||||
/* Get "reg" or "assigned-addresses" property */
|
||||
prop = of_get_property(dev, bus->addresses, &psize);
|
||||
if (prop == NULL)
|
||||
return NULL;
|
||||
psize /= 4;
|
||||
|
||||
onesize = na + ns;
|
||||
for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
|
||||
if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
|
||||
if (size)
|
||||
*size = of_read_number(prop + na, ns);
|
||||
if (flags)
|
||||
*flags = bus->get_flags(prop);
|
||||
return prop;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_pci_address);
|
||||
|
||||
int of_pci_address_to_resource(struct device_node *dev, int bar,
|
||||
struct resource *r)
|
||||
{
|
||||
const u32 *addrp;
|
||||
u64 size;
|
||||
unsigned int flags;
|
||||
|
||||
addrp = of_get_pci_address(dev, bar, &size, &flags);
|
||||
if (addrp == NULL)
|
||||
return -EINVAL;
|
||||
return __of_address_to_resource(dev, addrp, size, flags, r);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
|
||||
|
||||
int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
|
||||
{
|
||||
struct device_node *dn, *ppnode;
|
||||
|
@ -313,345 +92,6 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
|
|||
EXPORT_SYMBOL_GPL(of_irq_map_pci);
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
/*
|
||||
* ISA bus specific translator
|
||||
*/
|
||||
|
||||
static int of_bus_isa_match(struct device_node *np)
|
||||
{
|
||||
return !strcmp(np->name, "isa");
|
||||
}
|
||||
|
||||
static void of_bus_isa_count_cells(struct device_node *child,
|
||||
int *addrc, int *sizec)
|
||||
{
|
||||
if (addrc)
|
||||
*addrc = 2;
|
||||
if (sizec)
|
||||
*sizec = 1;
|
||||
}
|
||||
|
||||
static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
|
||||
{
|
||||
u64 cp, s, da;
|
||||
|
||||
/* Check address type match */
|
||||
if ((addr[0] ^ range[0]) & 0x00000001)
|
||||
return OF_BAD_ADDR;
|
||||
|
||||
/* Read address values, skipping high cell */
|
||||
cp = of_read_number(range + 1, na - 1);
|
||||
s = of_read_number(range + na + pna, ns);
|
||||
da = of_read_number(addr + 1, na - 1);
|
||||
|
||||
DBG("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da);
|
||||
|
||||
if (da < cp || da >= (cp + s))
|
||||
return OF_BAD_ADDR;
|
||||
return da - cp;
|
||||
}
|
||||
|
||||
static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
|
||||
{
|
||||
return of_bus_default_translate(addr + 1, offset, na - 1);
|
||||
}
|
||||
|
||||
static unsigned int of_bus_isa_get_flags(const u32 *addr)
|
||||
{
|
||||
unsigned int flags = 0;
|
||||
u32 w = addr[0];
|
||||
|
||||
if (w & 1)
|
||||
flags |= IORESOURCE_IO;
|
||||
else
|
||||
flags |= IORESOURCE_MEM;
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Array of bus specific translators
|
||||
*/
|
||||
|
||||
static struct of_bus of_busses[] = {
|
||||
#ifdef CONFIG_PCI
|
||||
/* PCI */
|
||||
{
|
||||
.name = "pci",
|
||||
.addresses = "assigned-addresses",
|
||||
.match = of_bus_pci_match,
|
||||
.count_cells = of_bus_pci_count_cells,
|
||||
.map = of_bus_pci_map,
|
||||
.translate = of_bus_pci_translate,
|
||||
.get_flags = of_bus_pci_get_flags,
|
||||
},
|
||||
#endif /* CONFIG_PCI */
|
||||
/* ISA */
|
||||
{
|
||||
.name = "isa",
|
||||
.addresses = "reg",
|
||||
.match = of_bus_isa_match,
|
||||
.count_cells = of_bus_isa_count_cells,
|
||||
.map = of_bus_isa_map,
|
||||
.translate = of_bus_isa_translate,
|
||||
.get_flags = of_bus_isa_get_flags,
|
||||
},
|
||||
/* Default */
|
||||
{
|
||||
.name = "default",
|
||||
.addresses = "reg",
|
||||
.match = NULL,
|
||||
.count_cells = of_bus_default_count_cells,
|
||||
.map = of_bus_default_map,
|
||||
.translate = of_bus_default_translate,
|
||||
.get_flags = of_bus_default_get_flags,
|
||||
},
|
||||
};
|
||||
|
||||
static struct of_bus *of_match_bus(struct device_node *np)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(of_busses); i ++)
|
||||
if (!of_busses[i].match || of_busses[i].match(np))
|
||||
return &of_busses[i];
|
||||
BUG();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int of_translate_one(struct device_node *parent, struct of_bus *bus,
|
||||
struct of_bus *pbus, u32 *addr,
|
||||
int na, int ns, int pna, const char *rprop)
|
||||
{
|
||||
const u32 *ranges;
|
||||
unsigned int rlen;
|
||||
int rone;
|
||||
u64 offset = OF_BAD_ADDR;
|
||||
|
||||
/* Normally, an absence of a "ranges" property means we are
|
||||
* crossing a non-translatable boundary, and thus the addresses
|
||||
* below the current not cannot be converted to CPU physical ones.
|
||||
* Unfortunately, while this is very clear in the spec, it's not
|
||||
* what Apple understood, and they do have things like /uni-n or
|
||||
* /ht nodes with no "ranges" property and a lot of perfectly
|
||||
* useable mapped devices below them. Thus we treat the absence of
|
||||
* "ranges" as equivalent to an empty "ranges" property which means
|
||||
* a 1:1 translation at that level. It's up to the caller not to try
|
||||
* to translate addresses that aren't supposed to be translated in
|
||||
* the first place. --BenH.
|
||||
*/
|
||||
ranges = of_get_property(parent, rprop, &rlen);
|
||||
if (ranges == NULL || rlen == 0) {
|
||||
offset = of_read_number(addr, na);
|
||||
memset(addr, 0, pna * 4);
|
||||
DBG("OF: no ranges, 1:1 translation\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
DBG("OF: walking ranges...\n");
|
||||
|
||||
/* Now walk through the ranges */
|
||||
rlen /= 4;
|
||||
rone = na + pna + ns;
|
||||
for (; rlen >= rone; rlen -= rone, ranges += rone) {
|
||||
offset = bus->map(addr, ranges, na, ns, pna);
|
||||
if (offset != OF_BAD_ADDR)
|
||||
break;
|
||||
}
|
||||
if (offset == OF_BAD_ADDR) {
|
||||
DBG("OF: not found !\n");
|
||||
return 1;
|
||||
}
|
||||
memcpy(addr, ranges + na, 4 * pna);
|
||||
|
||||
finish:
|
||||
of_dump_addr("OF: parent translation for:", addr, pna);
|
||||
DBG("OF: with offset: "PRu64"\n", offset);
|
||||
|
||||
/* Translate it into parent bus space */
|
||||
return pbus->translate(addr, offset, pna);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Translate an address from the device-tree into a CPU physical address,
|
||||
* this walks up the tree and applies the various bus mappings on the
|
||||
* way.
|
||||
*
|
||||
* Note: We consider that crossing any level with #size-cells == 0 to mean
|
||||
* that translation is impossible (that is we are not dealing with a value
|
||||
* that can be mapped to a cpu physical address). This is not really specified
|
||||
* that way, but this is traditionally the way IBM at least do things
|
||||
*/
|
||||
u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
|
||||
const char *rprop)
|
||||
{
|
||||
struct device_node *parent = NULL;
|
||||
struct of_bus *bus, *pbus;
|
||||
u32 addr[OF_MAX_ADDR_CELLS];
|
||||
int na, ns, pna, pns;
|
||||
u64 result = OF_BAD_ADDR;
|
||||
|
||||
DBG("OF: ** translation for device %s **\n", dev->full_name);
|
||||
|
||||
/* Increase refcount at current level */
|
||||
of_node_get(dev);
|
||||
|
||||
/* Get parent & match bus type */
|
||||
parent = of_get_parent(dev);
|
||||
if (parent == NULL)
|
||||
goto bail;
|
||||
bus = of_match_bus(parent);
|
||||
|
||||
/* Cound address cells & copy address locally */
|
||||
bus->count_cells(dev, &na, &ns);
|
||||
if (!OF_CHECK_COUNTS(na, ns)) {
|
||||
printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
|
||||
dev->full_name);
|
||||
goto bail;
|
||||
}
|
||||
memcpy(addr, in_addr, na * 4);
|
||||
|
||||
DBG("OF: bus is %s (na=%d, ns=%d) on %s\n",
|
||||
bus->name, na, ns, parent->full_name);
|
||||
of_dump_addr("OF: translating address:", addr, na);
|
||||
|
||||
/* Translate */
|
||||
for (;;) {
|
||||
/* Switch to parent bus */
|
||||
of_node_put(dev);
|
||||
dev = parent;
|
||||
parent = of_get_parent(dev);
|
||||
|
||||
/* If root, we have finished */
|
||||
if (parent == NULL) {
|
||||
DBG("OF: reached root node\n");
|
||||
result = of_read_number(addr, na);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get new parent bus and counts */
|
||||
pbus = of_match_bus(parent);
|
||||
pbus->count_cells(dev, &pna, &pns);
|
||||
if (!OF_CHECK_COUNTS(pna, pns)) {
|
||||
printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
|
||||
dev->full_name);
|
||||
break;
|
||||
}
|
||||
|
||||
DBG("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
|
||||
pbus->name, pna, pns, parent->full_name);
|
||||
|
||||
/* Apply bus translation */
|
||||
if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
|
||||
break;
|
||||
|
||||
/* Complete the move up one level */
|
||||
na = pna;
|
||||
ns = pns;
|
||||
bus = pbus;
|
||||
|
||||
of_dump_addr("OF: one level translation:", addr, na);
|
||||
}
|
||||
bail:
|
||||
of_node_put(parent);
|
||||
of_node_put(dev);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
|
||||
{
|
||||
return __of_translate_address(dev, in_addr, "ranges");
|
||||
}
|
||||
EXPORT_SYMBOL(of_translate_address);
|
||||
|
||||
u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr)
|
||||
{
|
||||
return __of_translate_address(dev, in_addr, "dma-ranges");
|
||||
}
|
||||
EXPORT_SYMBOL(of_translate_dma_address);
|
||||
|
||||
const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
|
||||
unsigned int *flags)
|
||||
{
|
||||
const u32 *prop;
|
||||
unsigned int psize;
|
||||
struct device_node *parent;
|
||||
struct of_bus *bus;
|
||||
int onesize, i, na, ns;
|
||||
|
||||
/* Get parent & match bus type */
|
||||
parent = of_get_parent(dev);
|
||||
if (parent == NULL)
|
||||
return NULL;
|
||||
bus = of_match_bus(parent);
|
||||
bus->count_cells(dev, &na, &ns);
|
||||
of_node_put(parent);
|
||||
if (!OF_CHECK_COUNTS(na, ns))
|
||||
return NULL;
|
||||
|
||||
/* Get "reg" or "assigned-addresses" property */
|
||||
prop = of_get_property(dev, bus->addresses, &psize);
|
||||
if (prop == NULL)
|
||||
return NULL;
|
||||
psize /= 4;
|
||||
|
||||
onesize = na + ns;
|
||||
for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
|
||||
if (i == index) {
|
||||
if (size)
|
||||
*size = of_read_number(prop + na, ns);
|
||||
if (flags)
|
||||
*flags = bus->get_flags(prop);
|
||||
return prop;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_address);
|
||||
|
||||
static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
|
||||
u64 size, unsigned int flags,
|
||||
struct resource *r)
|
||||
{
|
||||
u64 taddr;
|
||||
|
||||
if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
|
||||
return -EINVAL;
|
||||
taddr = of_translate_address(dev, addrp);
|
||||
if (taddr == OF_BAD_ADDR)
|
||||
return -EINVAL;
|
||||
memset(r, 0, sizeof(struct resource));
|
||||
if (flags & IORESOURCE_IO) {
|
||||
unsigned long port;
|
||||
port = pci_address_to_pio(taddr);
|
||||
if (port == (unsigned long)-1)
|
||||
return -EINVAL;
|
||||
r->start = port;
|
||||
r->end = port + size - 1;
|
||||
} else {
|
||||
r->start = taddr;
|
||||
r->end = taddr + size - 1;
|
||||
}
|
||||
r->flags = flags;
|
||||
r->name = dev->name;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int of_address_to_resource(struct device_node *dev, int index,
|
||||
struct resource *r)
|
||||
{
|
||||
const u32 *addrp;
|
||||
u64 size;
|
||||
unsigned int flags;
|
||||
|
||||
addrp = of_get_address(dev, index, &size, &flags);
|
||||
if (addrp == NULL)
|
||||
return -EINVAL;
|
||||
return __of_address_to_resource(dev, addrp, size, flags, r);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_address_to_resource);
|
||||
|
||||
void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
|
||||
unsigned long *busno, unsigned long *phys, unsigned long *size)
|
||||
{
|
||||
|
@ -678,342 +118,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
|
|||
*size = of_read_number(dma_window, cells);
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt remapper
|
||||
*/
|
||||
|
||||
static unsigned int of_irq_workarounds;
|
||||
static struct device_node *of_irq_dflt_pic;
|
||||
|
||||
static struct device_node *of_irq_find_parent(struct device_node *child)
|
||||
{
|
||||
struct device_node *p;
|
||||
const phandle *parp;
|
||||
|
||||
if (!of_node_get(child))
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
parp = of_get_property(child, "interrupt-parent", NULL);
|
||||
if (parp == NULL)
|
||||
p = of_get_parent(child);
|
||||
else {
|
||||
if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
|
||||
p = of_node_get(of_irq_dflt_pic);
|
||||
else
|
||||
p = of_find_node_by_phandle(*parp);
|
||||
}
|
||||
of_node_put(child);
|
||||
child = p;
|
||||
} while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* This doesn't need to be called if you don't have any special workaround
|
||||
* flags to pass
|
||||
*/
|
||||
void of_irq_map_init(unsigned int flags)
|
||||
{
|
||||
of_irq_workarounds = flags;
|
||||
|
||||
/* OldWorld, don't bother looking at other things */
|
||||
if (flags & OF_IMAP_OLDWORLD_MAC)
|
||||
return;
|
||||
|
||||
/* If we don't have phandles, let's try to locate a default interrupt
|
||||
* controller (happens when booting with BootX). We do a first match
|
||||
* here, hopefully, that only ever happens on machines with one
|
||||
* controller.
|
||||
*/
|
||||
if (flags & OF_IMAP_NO_PHANDLE) {
|
||||
struct device_node *np;
|
||||
|
||||
for_each_node_with_property(np, "interrupt-controller") {
|
||||
/* Skip /chosen/interrupt-controller */
|
||||
if (strcmp(np->name, "chosen") == 0)
|
||||
continue;
|
||||
/* It seems like at least one person on this planet wants
|
||||
* to use BootX on a machine with an AppleKiwi controller
|
||||
* which happens to pretend to be an interrupt
|
||||
* controller too.
|
||||
*/
|
||||
if (strcmp(np->name, "AppleKiwi") == 0)
|
||||
continue;
|
||||
/* I think we found one ! */
|
||||
of_irq_dflt_pic = np;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
|
||||
const u32 *addr, struct of_irq *out_irq)
|
||||
{
|
||||
struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
|
||||
const u32 *tmp, *imap, *imask;
|
||||
u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
|
||||
int imaplen, match, i;
|
||||
|
||||
DBG("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
|
||||
parent->full_name, intspec[0], intspec[1], ointsize);
|
||||
|
||||
ipar = of_node_get(parent);
|
||||
|
||||
/* First get the #interrupt-cells property of the current cursor
|
||||
* that tells us how to interpret the passed-in intspec. If there
|
||||
* is none, we are nice and just walk up the tree
|
||||
*/
|
||||
do {
|
||||
tmp = of_get_property(ipar, "#interrupt-cells", NULL);
|
||||
if (tmp != NULL) {
|
||||
intsize = *tmp;
|
||||
break;
|
||||
}
|
||||
tnode = ipar;
|
||||
ipar = of_irq_find_parent(ipar);
|
||||
of_node_put(tnode);
|
||||
} while (ipar);
|
||||
if (ipar == NULL) {
|
||||
DBG(" -> no parent found !\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
DBG("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize);
|
||||
|
||||
if (ointsize != intsize)
|
||||
return -EINVAL;
|
||||
|
||||
/* Look for this #address-cells. We have to implement the old linux
|
||||
* trick of looking for the parent here as some device-trees rely on it
|
||||
*/
|
||||
old = of_node_get(ipar);
|
||||
do {
|
||||
tmp = of_get_property(old, "#address-cells", NULL);
|
||||
tnode = of_get_parent(old);
|
||||
of_node_put(old);
|
||||
old = tnode;
|
||||
} while(old && tmp == NULL);
|
||||
of_node_put(old);
|
||||
old = NULL;
|
||||
addrsize = (tmp == NULL) ? 2 : *tmp;
|
||||
|
||||
DBG(" -> addrsize=%d\n", addrsize);
|
||||
|
||||
/* Now start the actual "proper" walk of the interrupt tree */
|
||||
while (ipar != NULL) {
|
||||
/* Now check if cursor is an interrupt-controller and if it is
|
||||
* then we are done
|
||||
*/
|
||||
if (of_get_property(ipar, "interrupt-controller", NULL) !=
|
||||
NULL) {
|
||||
DBG(" -> got it !\n");
|
||||
memcpy(out_irq->specifier, intspec,
|
||||
intsize * sizeof(u32));
|
||||
out_irq->size = intsize;
|
||||
out_irq->controller = ipar;
|
||||
of_node_put(old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Now look for an interrupt-map */
|
||||
imap = of_get_property(ipar, "interrupt-map", &imaplen);
|
||||
/* No interrupt map, check for an interrupt parent */
|
||||
if (imap == NULL) {
|
||||
DBG(" -> no map, getting parent\n");
|
||||
newpar = of_irq_find_parent(ipar);
|
||||
goto skiplevel;
|
||||
}
|
||||
imaplen /= sizeof(u32);
|
||||
|
||||
/* Look for a mask */
|
||||
imask = of_get_property(ipar, "interrupt-map-mask", NULL);
|
||||
|
||||
/* If we were passed no "reg" property and we attempt to parse
|
||||
* an interrupt-map, then #address-cells must be 0.
|
||||
* Fail if it's not.
|
||||
*/
|
||||
if (addr == NULL && addrsize != 0) {
|
||||
DBG(" -> no reg passed in when needed !\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Parse interrupt-map */
|
||||
match = 0;
|
||||
while (imaplen > (addrsize + intsize + 1) && !match) {
|
||||
/* Compare specifiers */
|
||||
match = 1;
|
||||
for (i = 0; i < addrsize && match; ++i) {
|
||||
u32 mask = imask ? imask[i] : 0xffffffffu;
|
||||
match = ((addr[i] ^ imap[i]) & mask) == 0;
|
||||
}
|
||||
for (; i < (addrsize + intsize) && match; ++i) {
|
||||
u32 mask = imask ? imask[i] : 0xffffffffu;
|
||||
match =
|
||||
((intspec[i-addrsize] ^ imap[i]) & mask) == 0;
|
||||
}
|
||||
imap += addrsize + intsize;
|
||||
imaplen -= addrsize + intsize;
|
||||
|
||||
DBG(" -> match=%d (imaplen=%d)\n", match, imaplen);
|
||||
|
||||
/* Get the interrupt parent */
|
||||
if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
|
||||
newpar = of_node_get(of_irq_dflt_pic);
|
||||
else
|
||||
newpar = of_find_node_by_phandle((phandle)*imap);
|
||||
imap++;
|
||||
--imaplen;
|
||||
|
||||
/* Check if not found */
|
||||
if (newpar == NULL) {
|
||||
DBG(" -> imap parent not found !\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Get #interrupt-cells and #address-cells of new
|
||||
* parent
|
||||
*/
|
||||
tmp = of_get_property(newpar, "#interrupt-cells", NULL);
|
||||
if (tmp == NULL) {
|
||||
DBG(" -> parent lacks #interrupt-cells !\n");
|
||||
goto fail;
|
||||
}
|
||||
newintsize = *tmp;
|
||||
tmp = of_get_property(newpar, "#address-cells", NULL);
|
||||
newaddrsize = (tmp == NULL) ? 0 : *tmp;
|
||||
|
||||
DBG(" -> newintsize=%d, newaddrsize=%d\n",
|
||||
newintsize, newaddrsize);
|
||||
|
||||
/* Check for malformed properties */
|
||||
if (imaplen < (newaddrsize + newintsize))
|
||||
goto fail;
|
||||
|
||||
imap += newaddrsize + newintsize;
|
||||
imaplen -= newaddrsize + newintsize;
|
||||
|
||||
DBG(" -> imaplen=%d\n", imaplen);
|
||||
}
|
||||
if (!match)
|
||||
goto fail;
|
||||
|
||||
of_node_put(old);
|
||||
old = of_node_get(newpar);
|
||||
addrsize = newaddrsize;
|
||||
intsize = newintsize;
|
||||
intspec = imap - intsize;
|
||||
addr = intspec - addrsize;
|
||||
|
||||
skiplevel:
|
||||
/* Iterate again with new parent */
|
||||
DBG(" -> new parent: %s\n", newpar ? newpar->full_name : "<>");
|
||||
of_node_put(ipar);
|
||||
ipar = newpar;
|
||||
newpar = NULL;
|
||||
}
|
||||
fail:
|
||||
of_node_put(ipar);
|
||||
of_node_put(old);
|
||||
of_node_put(newpar);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_irq_map_raw);
|
||||
|
||||
#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)
|
||||
static int of_irq_map_oldworld(struct device_node *device, int index,
|
||||
struct of_irq *out_irq)
|
||||
{
|
||||
const u32 *ints = NULL;
|
||||
int intlen;
|
||||
|
||||
/*
|
||||
* Old machines just have a list of interrupt numbers
|
||||
* and no interrupt-controller nodes. We also have dodgy
|
||||
* cases where the APPL,interrupts property is completely
|
||||
* missing behind pci-pci bridges and we have to get it
|
||||
* from the parent (the bridge itself, as apple just wired
|
||||
* everything together on these)
|
||||
*/
|
||||
while (device) {
|
||||
ints = of_get_property(device, "AAPL,interrupts", &intlen);
|
||||
if (ints != NULL)
|
||||
break;
|
||||
device = device->parent;
|
||||
if (device && strcmp(device->type, "pci") != 0)
|
||||
break;
|
||||
}
|
||||
if (ints == NULL)
|
||||
return -EINVAL;
|
||||
intlen /= sizeof(u32);
|
||||
|
||||
if (index >= intlen)
|
||||
return -EINVAL;
|
||||
|
||||
out_irq->controller = NULL;
|
||||
out_irq->specifier[0] = ints[index];
|
||||
out_irq->size = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else /* defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) */
|
||||
static int of_irq_map_oldworld(struct device_node *device, int index,
|
||||
struct of_irq *out_irq)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif /* !(defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32)) */
|
||||
|
||||
int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
|
||||
{
|
||||
struct device_node *p;
|
||||
const u32 *intspec, *tmp, *addr;
|
||||
u32 intsize, intlen;
|
||||
int res = -EINVAL;
|
||||
|
||||
DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
|
||||
|
||||
/* OldWorld mac stuff is "special", handle out of line */
|
||||
if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC)
|
||||
return of_irq_map_oldworld(device, index, out_irq);
|
||||
|
||||
/* Get the interrupts property */
|
||||
intspec = of_get_property(device, "interrupts", &intlen);
|
||||
if (intspec == NULL)
|
||||
return -EINVAL;
|
||||
intlen /= sizeof(u32);
|
||||
|
||||
/* Get the reg property (if any) */
|
||||
addr = of_get_property(device, "reg", NULL);
|
||||
|
||||
/* Look for the interrupt parent. */
|
||||
p = of_irq_find_parent(device);
|
||||
if (p == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/* Get size of interrupt specifier */
|
||||
tmp = of_get_property(p, "#interrupt-cells", NULL);
|
||||
if (tmp == NULL)
|
||||
goto out;
|
||||
intsize = *tmp;
|
||||
|
||||
DBG(" intsize=%d intlen=%d\n", intsize, intlen);
|
||||
|
||||
/* Check index */
|
||||
if ((index + 1) * intsize > intlen)
|
||||
goto out;
|
||||
|
||||
/* Get new specifier and map it */
|
||||
res = of_irq_map_raw(p, intspec + index * intsize, intsize,
|
||||
addr, out_irq);
|
||||
out:
|
||||
of_node_put(p);
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_irq_map_one);
|
||||
|
||||
/**
|
||||
* Search the device tree for the best MAC address to use. 'mac-address' is
|
||||
* checked first, because that is supposed to contain to "most recent" MAC
|
||||
|
@ -1051,29 +155,3 @@ const void *of_get_mac_address(struct device_node *np)
|
|||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_mac_address);
|
||||
|
||||
int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
|
||||
{
|
||||
int irq = irq_of_parse_and_map(dev, index);
|
||||
|
||||
/* Only dereference the resource if both the
|
||||
* resource and the irq are valid. */
|
||||
if (r && irq != NO_IRQ) {
|
||||
r->start = r->end = irq;
|
||||
r->flags = IORESOURCE_IRQ;
|
||||
}
|
||||
|
||||
return irq;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_irq_to_resource);
|
||||
|
||||
void __iomem *of_iomap(struct device_node *np, int index)
|
||||
{
|
||||
struct resource res;
|
||||
|
||||
if (of_address_to_resource(np, index, &res))
|
||||
return NULL;
|
||||
|
||||
return ioremap(res.start, 1 + res.end - res.start);
|
||||
}
|
||||
EXPORT_SYMBOL(of_iomap);
|
||||
|
|
|
@ -714,16 +714,9 @@ static struct notifier_block ppc_dflt_plat_bus_notifier = {
|
|||
.priority = INT_MAX,
|
||||
};
|
||||
|
||||
static struct notifier_block ppc_dflt_of_bus_notifier = {
|
||||
.notifier_call = ppc_dflt_bus_notify,
|
||||
.priority = INT_MAX,
|
||||
};
|
||||
|
||||
static int __init setup_bus_notifier(void)
|
||||
{
|
||||
bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier);
|
||||
bus_register_notifier(&of_platform_bus_type, &ppc_dflt_of_bus_notifier);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -678,7 +678,7 @@ static void psc_clks_init(void)
|
|||
{
|
||||
struct device_node *np;
|
||||
const u32 *cell_index;
|
||||
struct of_device *ofdev;
|
||||
struct platform_device *ofdev;
|
||||
|
||||
for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") {
|
||||
cell_index = of_get_property(np, "cell-index", NULL);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/root_dev.h>
|
||||
#include <linux/initrd.h>
|
||||
#include <asm/time.h>
|
||||
|
|
|
@ -147,26 +147,25 @@ mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev,
|
||||
static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct mpc52xx_gpiochip *chip;
|
||||
struct mpc52xx_gpio_wkup __iomem *regs;
|
||||
struct of_gpio_chip *ofchip;
|
||||
struct gpio_chip *gc;
|
||||
int ret;
|
||||
|
||||
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
|
||||
ofchip = &chip->mmchip.of_gc;
|
||||
gc = &chip->mmchip.gc;
|
||||
|
||||
ofchip->gpio_cells = 2;
|
||||
ofchip->gc.ngpio = 8;
|
||||
ofchip->gc.direction_input = mpc52xx_wkup_gpio_dir_in;
|
||||
ofchip->gc.direction_output = mpc52xx_wkup_gpio_dir_out;
|
||||
ofchip->gc.get = mpc52xx_wkup_gpio_get;
|
||||
ofchip->gc.set = mpc52xx_wkup_gpio_set;
|
||||
gc->ngpio = 8;
|
||||
gc->direction_input = mpc52xx_wkup_gpio_dir_in;
|
||||
gc->direction_output = mpc52xx_wkup_gpio_dir_out;
|
||||
gc->get = mpc52xx_wkup_gpio_get;
|
||||
gc->set = mpc52xx_wkup_gpio_set;
|
||||
|
||||
ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip);
|
||||
if (ret)
|
||||
|
@ -180,7 +179,7 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mpc52xx_gpiochip_remove(struct of_device *ofdev)
|
||||
static int mpc52xx_gpiochip_remove(struct platform_device *ofdev)
|
||||
{
|
||||
return -EBUSY;
|
||||
}
|
||||
|
@ -311,11 +310,11 @@ mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev,
|
||||
static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct mpc52xx_gpiochip *chip;
|
||||
struct of_gpio_chip *ofchip;
|
||||
struct gpio_chip *gc;
|
||||
struct mpc52xx_gpio __iomem *regs;
|
||||
int ret;
|
||||
|
||||
|
@ -323,14 +322,13 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev,
|
|||
if (!chip)
|
||||
return -ENOMEM;
|
||||
|
||||
ofchip = &chip->mmchip.of_gc;
|
||||
gc = &chip->mmchip.gc;
|
||||
|
||||
ofchip->gpio_cells = 2;
|
||||
ofchip->gc.ngpio = 32;
|
||||
ofchip->gc.direction_input = mpc52xx_simple_gpio_dir_in;
|
||||
ofchip->gc.direction_output = mpc52xx_simple_gpio_dir_out;
|
||||
ofchip->gc.get = mpc52xx_simple_gpio_get;
|
||||
ofchip->gc.set = mpc52xx_simple_gpio_set;
|
||||
gc->ngpio = 32;
|
||||
gc->direction_input = mpc52xx_simple_gpio_dir_in;
|
||||
gc->direction_output = mpc52xx_simple_gpio_dir_out;
|
||||
gc->get = mpc52xx_simple_gpio_get;
|
||||
gc->set = mpc52xx_simple_gpio_set;
|
||||
|
||||
ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip);
|
||||
if (ret)
|
||||
|
|
|
@ -78,7 +78,7 @@ MODULE_LICENSE("GPL");
|
|||
* @dev: pointer to device structure
|
||||
* @regs: virtual address of GPT registers
|
||||
* @lock: spinlock to coordinate between different functions.
|
||||
* @of_gc: of_gpio_chip instance structure; used when GPIO is enabled
|
||||
* @gc: gpio_chip instance structure; used when GPIO is enabled
|
||||
* @irqhost: Pointer to irq_host instance; used when IRQ mode is supported
|
||||
* @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates
|
||||
* if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates
|
||||
|
@ -94,7 +94,7 @@ struct mpc52xx_gpt_priv {
|
|||
u8 wdt_mode;
|
||||
|
||||
#if defined(CONFIG_GPIOLIB)
|
||||
struct of_gpio_chip of_gc;
|
||||
struct gpio_chip gc;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -280,7 +280,7 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
|
|||
#if defined(CONFIG_GPIOLIB)
|
||||
static inline struct mpc52xx_gpt_priv *gc_to_mpc52xx_gpt(struct gpio_chip *gc)
|
||||
{
|
||||
return container_of(to_of_gpio_chip(gc), struct mpc52xx_gpt_priv,of_gc);
|
||||
return container_of(gc, struct mpc52xx_gpt_priv, gc);
|
||||
}
|
||||
|
||||
static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio)
|
||||
|
@ -336,28 +336,25 @@ mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
|
|||
if (!of_find_property(node, "gpio-controller", NULL))
|
||||
return;
|
||||
|
||||
gpt->of_gc.gc.label = kstrdup(node->full_name, GFP_KERNEL);
|
||||
if (!gpt->of_gc.gc.label) {
|
||||
gpt->gc.label = kstrdup(node->full_name, GFP_KERNEL);
|
||||
if (!gpt->gc.label) {
|
||||
dev_err(gpt->dev, "out of memory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
gpt->of_gc.gpio_cells = 2;
|
||||
gpt->of_gc.gc.ngpio = 1;
|
||||
gpt->of_gc.gc.direction_input = mpc52xx_gpt_gpio_dir_in;
|
||||
gpt->of_gc.gc.direction_output = mpc52xx_gpt_gpio_dir_out;
|
||||
gpt->of_gc.gc.get = mpc52xx_gpt_gpio_get;
|
||||
gpt->of_gc.gc.set = mpc52xx_gpt_gpio_set;
|
||||
gpt->of_gc.gc.base = -1;
|
||||
gpt->of_gc.xlate = of_gpio_simple_xlate;
|
||||
node->data = &gpt->of_gc;
|
||||
of_node_get(node);
|
||||
gpt->gc.ngpio = 1;
|
||||
gpt->gc.direction_input = mpc52xx_gpt_gpio_dir_in;
|
||||
gpt->gc.direction_output = mpc52xx_gpt_gpio_dir_out;
|
||||
gpt->gc.get = mpc52xx_gpt_gpio_get;
|
||||
gpt->gc.set = mpc52xx_gpt_gpio_set;
|
||||
gpt->gc.base = -1;
|
||||
gpt->gc.of_node = node;
|
||||
|
||||
/* Setup external pin in GPIO mode */
|
||||
clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK,
|
||||
MPC52xx_GPT_MODE_MS_GPIO);
|
||||
|
||||
rc = gpiochip_add(&gpt->of_gc.gc);
|
||||
rc = gpiochip_add(&gpt->gc);
|
||||
if (rc)
|
||||
dev_err(gpt->dev, "gpiochip_add() failed; rc=%i\n", rc);
|
||||
|
||||
|
@ -723,7 +720,7 @@ static inline int mpc52xx_gpt_wdt_setup(struct mpc52xx_gpt_priv *gpt,
|
|||
/* ---------------------------------------------------------------------
|
||||
* of_platform bus binding code
|
||||
*/
|
||||
static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev,
|
||||
static int __devinit mpc52xx_gpt_probe(struct platform_device *ofdev,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct mpc52xx_gpt_priv *gpt;
|
||||
|
@ -769,7 +766,7 @@ static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mpc52xx_gpt_remove(struct of_device *ofdev)
|
||||
static int mpc52xx_gpt_remove(struct platform_device *ofdev)
|
||||
{
|
||||
return -EBUSY;
|
||||
}
|
||||
|
|
|
@ -436,8 +436,8 @@ void mpc52xx_lpbfifo_abort(struct mpc52xx_lpbfifo_request *req)
|
|||
}
|
||||
EXPORT_SYMBOL(mpc52xx_lpbfifo_abort);
|
||||
|
||||
static int __devinit
|
||||
mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match)
|
||||
static int __devinit mpc52xx_lpbfifo_probe(struct platform_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct resource res;
|
||||
int rc = -ENOMEM;
|
||||
|
@ -507,7 +507,7 @@ mpc52xx_lpbfifo_probe(struct of_device *op, const struct of_device_id *match)
|
|||
}
|
||||
|
||||
|
||||
static int __devexit mpc52xx_lpbfifo_remove(struct of_device *op)
|
||||
static int __devexit mpc52xx_lpbfifo_remove(struct platform_device *op)
|
||||
{
|
||||
if (lpbfifo.dev != &op->dev)
|
||||
return 0;
|
||||
|
|
|
@ -111,7 +111,7 @@ static struct mdiobb_ctrl ep8248e_mdio_ctrl = {
|
|||
.ops = &ep8248e_mdio_ops,
|
||||
};
|
||||
|
||||
static int __devinit ep8248e_mdio_probe(struct of_device *ofdev,
|
||||
static int __devinit ep8248e_mdio_probe(struct platform_device *ofdev,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct mii_bus *bus;
|
||||
|
@ -154,7 +154,7 @@ err_free_bus:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ep8248e_mdio_remove(struct of_device *ofdev)
|
||||
static int ep8248e_mdio_remove(struct platform_device *ofdev)
|
||||
{
|
||||
BUG();
|
||||
return 0;
|
||||
|
|
|
@ -35,9 +35,8 @@
|
|||
|
||||
struct mcu {
|
||||
struct mutex lock;
|
||||
struct device_node *np;
|
||||
struct i2c_client *client;
|
||||
struct of_gpio_chip of_gc;
|
||||
struct gpio_chip gc;
|
||||
u8 reg_ctrl;
|
||||
};
|
||||
|
||||
|
@ -56,8 +55,7 @@ static void mcu_power_off(void)
|
|||
|
||||
static void mcu_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
|
||||
{
|
||||
struct of_gpio_chip *of_gc = to_of_gpio_chip(gc);
|
||||
struct mcu *mcu = container_of(of_gc, struct mcu, of_gc);
|
||||
struct mcu *mcu = container_of(gc, struct mcu, gc);
|
||||
u8 bit = 1 << (4 + gpio);
|
||||
|
||||
mutex_lock(&mcu->lock);
|
||||
|
@ -79,9 +77,7 @@ static int mcu_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
|
|||
static int mcu_gpiochip_add(struct mcu *mcu)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct of_gpio_chip *of_gc = &mcu->of_gc;
|
||||
struct gpio_chip *gc = &of_gc->gc;
|
||||
int ret;
|
||||
struct gpio_chip *gc = &mcu->gc;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,mcu-mpc8349emitx");
|
||||
if (!np)
|
||||
|
@ -94,32 +90,14 @@ static int mcu_gpiochip_add(struct mcu *mcu)
|
|||
gc->base = -1;
|
||||
gc->set = mcu_gpio_set;
|
||||
gc->direction_output = mcu_gpio_dir_out;
|
||||
of_gc->gpio_cells = 2;
|
||||
of_gc->xlate = of_gpio_simple_xlate;
|
||||
gc->of_node = np;
|
||||
|
||||
np->data = of_gc;
|
||||
mcu->np = np;
|
||||
|
||||
/*
|
||||
* We don't want to lose the node, its ->data and ->full_name...
|
||||
* So, if succeeded, we don't put the node here.
|
||||
*/
|
||||
ret = gpiochip_add(gc);
|
||||
if (ret)
|
||||
of_node_put(np);
|
||||
return ret;
|
||||
return gpiochip_add(gc);
|
||||
}
|
||||
|
||||
static int mcu_gpiochip_remove(struct mcu *mcu)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = gpiochip_remove(&mcu->of_gc.gc);
|
||||
if (ret)
|
||||
return ret;
|
||||
of_node_put(mcu->np);
|
||||
|
||||
return 0;
|
||||
return gpiochip_remove(&mcu->gc);
|
||||
}
|
||||
|
||||
static int __devinit mcu_probe(struct i2c_client *client,
|
||||
|
@ -182,10 +160,16 @@ static const struct i2c_device_id mcu_ids[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(i2c, mcu_ids);
|
||||
|
||||
static struct of_device_id mcu_of_match_table[] __devinitdata = {
|
||||
{ .compatible = "fsl,mcu-mpc8349emitx", },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct i2c_driver mcu_driver = {
|
||||
.driver = {
|
||||
.name = "mcu-mpc8349emitx",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = mcu_of_match_table,
|
||||
},
|
||||
.probe = mcu_probe,
|
||||
.remove = __devexit_p(mcu_remove),
|
||||
|
|
|
@ -99,7 +99,7 @@ struct pmc_type {
|
|||
int has_deep_sleep;
|
||||
};
|
||||
|
||||
static struct of_device *pmc_dev;
|
||||
static struct platform_device *pmc_dev;
|
||||
static int has_deep_sleep, deep_sleeping;
|
||||
static int pmc_irq;
|
||||
static struct mpc83xx_pmc __iomem *pmc_regs;
|
||||
|
@ -318,7 +318,7 @@ static struct platform_suspend_ops mpc83xx_suspend_ops = {
|
|||
.end = mpc83xx_suspend_end,
|
||||
};
|
||||
|
||||
static int pmc_probe(struct of_device *ofdev,
|
||||
static int pmc_probe(struct platform_device *ofdev,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct device_node *np = ofdev->dev.of_node;
|
||||
|
@ -396,7 +396,7 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int pmc_remove(struct of_device *ofdev)
|
||||
static int pmc_remove(struct platform_device *ofdev)
|
||||
{
|
||||
return -EPERM;
|
||||
};
|
||||
|
|
|
@ -118,12 +118,12 @@ static int __init gef_gpio_init(void)
|
|||
}
|
||||
|
||||
/* Setup pointers to chip functions */
|
||||
gef_gpio_chip->of_gc.gpio_cells = 2;
|
||||
gef_gpio_chip->of_gc.gc.ngpio = 19;
|
||||
gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in;
|
||||
gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out;
|
||||
gef_gpio_chip->of_gc.gc.get = gef_gpio_get;
|
||||
gef_gpio_chip->of_gc.gc.set = gef_gpio_set;
|
||||
gef_gpio_chip->gc.of_gpio_n_cells = 2;
|
||||
gef_gpio_chip->gc.ngpio = 19;
|
||||
gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
|
||||
gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
|
||||
gef_gpio_chip->gc.get = gef_gpio_get;
|
||||
gef_gpio_chip->gc.set = gef_gpio_set;
|
||||
|
||||
/* This function adds a memory mapped GPIO chip */
|
||||
retval = of_mm_gpiochip_add(np, gef_gpio_chip);
|
||||
|
@ -146,12 +146,12 @@ static int __init gef_gpio_init(void)
|
|||
}
|
||||
|
||||
/* Setup pointers to chip functions */
|
||||
gef_gpio_chip->of_gc.gpio_cells = 2;
|
||||
gef_gpio_chip->of_gc.gc.ngpio = 6;
|
||||
gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in;
|
||||
gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out;
|
||||
gef_gpio_chip->of_gc.gc.get = gef_gpio_get;
|
||||
gef_gpio_chip->of_gc.gc.set = gef_gpio_set;
|
||||
gef_gpio_chip->gc.of_gpio_n_cells = 2;
|
||||
gef_gpio_chip->gc.ngpio = 6;
|
||||
gef_gpio_chip->gc.direction_input = gef_gpio_dir_in;
|
||||
gef_gpio_chip->gc.direction_output = gef_gpio_dir_out;
|
||||
gef_gpio_chip->gc.get = gef_gpio_get;
|
||||
gef_gpio_chip->gc.set = gef_gpio_set;
|
||||
|
||||
/* This function adds a memory mapped GPIO chip */
|
||||
retval = of_mm_gpiochip_add(np, gef_gpio_chip);
|
||||
|
|
|
@ -13,12 +13,13 @@
|
|||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <generated/utsrelease.h>
|
||||
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/cputable.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/i8259.h>
|
||||
#include <asm/time.h>
|
||||
|
|
|
@ -328,7 +328,7 @@ static struct irq_host_ops msic_host_ops = {
|
|||
.map = msic_host_map,
|
||||
};
|
||||
|
||||
static int axon_msi_shutdown(struct of_device *device)
|
||||
static int axon_msi_shutdown(struct platform_device *device)
|
||||
{
|
||||
struct axon_msic *msic = dev_get_drvdata(&device->dev);
|
||||
u32 tmp;
|
||||
|
@ -342,7 +342,7 @@ static int axon_msi_shutdown(struct of_device *device)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int axon_msi_probe(struct of_device *device,
|
||||
static int axon_msi_probe(struct platform_device *device,
|
||||
const struct of_device_id *device_id)
|
||||
{
|
||||
struct device_node *dn = device->dev.of_node;
|
||||
|
|
|
@ -108,7 +108,7 @@ static int __init celleb_init_iommu(void)
|
|||
celleb_init_direct_mapping();
|
||||
set_pci_dma_ops(&dma_direct_ops);
|
||||
ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup;
|
||||
bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier);
|
||||
bus_register_notifier(&platform_bus_type, &celleb_of_bus_notifier);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1204,7 +1204,7 @@ static int __init cell_iommu_init(void)
|
|||
/* Register callbacks on OF platform device addition/removal
|
||||
* to handle linking them to the right DMA operations
|
||||
*/
|
||||
bus_register_notifier(&of_platform_bus_type, &cell_of_bus_notifier);
|
||||
bus_register_notifier(&platform_bus_type, &cell_of_bus_notifier);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -61,12 +61,24 @@ static void qpace_progress(char *s, unsigned short hex)
|
|||
printk("*** %04x : %s\n", hex, s ? s : "");
|
||||
}
|
||||
|
||||
static const struct of_device_id qpace_bus_ids[] __initdata = {
|
||||
{ .type = "soc", },
|
||||
{ .compatible = "soc", },
|
||||
{ .type = "spider", },
|
||||
{ .type = "axon", },
|
||||
{ .type = "plb5", },
|
||||
{ .type = "plb4", },
|
||||
{ .type = "opb", },
|
||||
{ .type = "ebc", },
|
||||
{},
|
||||
};
|
||||
|
||||
static int __init qpace_publish_devices(void)
|
||||
{
|
||||
int node;
|
||||
|
||||
/* Publish OF platform devices for southbridge IOs */
|
||||
of_platform_bus_probe(NULL, NULL, NULL);
|
||||
of_platform_bus_probe(NULL, qpace_bus_ids, NULL);
|
||||
|
||||
/* There is no device for the MIC memory controller, thus we create
|
||||
* a platform device for it to attach the EDAC driver to.
|
||||
|
|
|
@ -141,6 +141,18 @@ static int __devinit cell_setup_phb(struct pci_controller *phb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id cell_bus_ids[] __initdata = {
|
||||
{ .type = "soc", },
|
||||
{ .compatible = "soc", },
|
||||
{ .type = "spider", },
|
||||
{ .type = "axon", },
|
||||
{ .type = "plb5", },
|
||||
{ .type = "plb4", },
|
||||
{ .type = "opb", },
|
||||
{ .type = "ebc", },
|
||||
{},
|
||||
};
|
||||
|
||||
static int __init cell_publish_devices(void)
|
||||
{
|
||||
struct device_node *root = of_find_node_by_path("/");
|
||||
|
@ -148,7 +160,7 @@ static int __init cell_publish_devices(void)
|
|||
int node;
|
||||
|
||||
/* Publish OF platform devices for southbridge IOs */
|
||||
of_platform_bus_probe(NULL, NULL, NULL);
|
||||
of_platform_bus_probe(NULL, cell_bus_ids, NULL);
|
||||
|
||||
/* On spider based blades, we need to manually create the OF
|
||||
* platform devices for the PCI host bridges
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/rtc.h>
|
||||
|
|
|
@ -216,7 +216,7 @@ static int gpio_mdio_reset(struct mii_bus *bus)
|
|||
}
|
||||
|
||||
|
||||
static int __devinit gpio_mdio_probe(struct of_device *ofdev,
|
||||
static int __devinit gpio_mdio_probe(struct platform_device *ofdev,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct device *dev = &ofdev->dev;
|
||||
|
@ -275,7 +275,7 @@ out:
|
|||
}
|
||||
|
||||
|
||||
static int gpio_mdio_remove(struct of_device *dev)
|
||||
static int gpio_mdio_remove(struct platform_device *dev)
|
||||
{
|
||||
struct mii_bus *bus = dev_get_drvdata(&dev->dev);
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/adb.h>
|
||||
#include <linux/pmu.h>
|
||||
|
|
|
@ -46,6 +46,10 @@ struct pmac_irq_hw {
|
|||
unsigned int level;
|
||||
};
|
||||
|
||||
/* Workaround flags for 32bit powermac machines */
|
||||
unsigned int of_irq_workarounds;
|
||||
struct device_node *of_irq_dflt_pic;
|
||||
|
||||
/* Default addresses */
|
||||
static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4];
|
||||
|
||||
|
@ -428,6 +432,42 @@ static void __init pmac_pic_probe_oldstyle(void)
|
|||
setup_irq(irq_create_mapping(NULL, 20), &xmon_action);
|
||||
#endif
|
||||
}
|
||||
|
||||
int of_irq_map_oldworld(struct device_node *device, int index,
|
||||
struct of_irq *out_irq)
|
||||
{
|
||||
const u32 *ints = NULL;
|
||||
int intlen;
|
||||
|
||||
/*
|
||||
* Old machines just have a list of interrupt numbers
|
||||
* and no interrupt-controller nodes. We also have dodgy
|
||||
* cases where the APPL,interrupts property is completely
|
||||
* missing behind pci-pci bridges and we have to get it
|
||||
* from the parent (the bridge itself, as apple just wired
|
||||
* everything together on these)
|
||||
*/
|
||||
while (device) {
|
||||
ints = of_get_property(device, "AAPL,interrupts", &intlen);
|
||||
if (ints != NULL)
|
||||
break;
|
||||
device = device->parent;
|
||||
if (device && strcmp(device->type, "pci") != 0)
|
||||
break;
|
||||
}
|
||||
if (ints == NULL)
|
||||
return -EINVAL;
|
||||
intlen /= sizeof(u32);
|
||||
|
||||
if (index >= intlen)
|
||||
return -EINVAL;
|
||||
|
||||
out_irq->controller = NULL;
|
||||
out_irq->specifier[0] = ints[index];
|
||||
out_irq->size = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PPC32 */
|
||||
|
||||
static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc)
|
||||
|
@ -559,19 +599,39 @@ static int __init pmac_pic_probe_mpic(void)
|
|||
|
||||
void __init pmac_pic_init(void)
|
||||
{
|
||||
unsigned int flags = 0;
|
||||
|
||||
/* We configure the OF parsing based on our oldworld vs. newworld
|
||||
* platform type and wether we were booted by BootX.
|
||||
*/
|
||||
#ifdef CONFIG_PPC32
|
||||
if (!pmac_newworld)
|
||||
flags |= OF_IMAP_OLDWORLD_MAC;
|
||||
of_irq_workarounds |= OF_IMAP_OLDWORLD_MAC;
|
||||
if (of_get_property(of_chosen, "linux,bootx", NULL) != NULL)
|
||||
flags |= OF_IMAP_NO_PHANDLE;
|
||||
#endif /* CONFIG_PPC_32 */
|
||||
of_irq_workarounds |= OF_IMAP_NO_PHANDLE;
|
||||
|
||||
of_irq_map_init(flags);
|
||||
/* If we don't have phandles on a newworld, then try to locate a
|
||||
* default interrupt controller (happens when booting with BootX).
|
||||
* We do a first match here, hopefully, that only ever happens on
|
||||
* machines with one controller.
|
||||
*/
|
||||
if (pmac_newworld && (of_irq_workarounds & OF_IMAP_NO_PHANDLE)) {
|
||||
struct device_node *np;
|
||||
|
||||
for_each_node_with_property(np, "interrupt-controller") {
|
||||
/* Skip /chosen/interrupt-controller */
|
||||
if (strcmp(np->name, "chosen") == 0)
|
||||
continue;
|
||||
/* It seems like at least one person wants
|
||||
* to use BootX on a machine with an AppleKiwi
|
||||
* controller which happens to pretend to be an
|
||||
* interrupt controller too. */
|
||||
if (strcmp(np->name, "AppleKiwi") == 0)
|
||||
continue;
|
||||
/* I think we found one ! */
|
||||
of_irq_dflt_pic = np;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_PPC32 */
|
||||
|
||||
/* We first try to detect Apple's new Core99 chipset, since mac-io
|
||||
* is quite different on those machines and contains an IBM MPIC2.
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
static int azfs_major, azfs_minor;
|
||||
|
||||
struct axon_ram_bank {
|
||||
struct of_device *device;
|
||||
struct platform_device *device;
|
||||
struct gendisk *disk;
|
||||
unsigned int irq_id;
|
||||
unsigned long ph_addr;
|
||||
|
@ -72,7 +72,7 @@ struct axon_ram_bank {
|
|||
static ssize_t
|
||||
axon_ram_sysfs_ecc(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct of_device *device = to_of_device(dev);
|
||||
struct platform_device *device = to_platform_device(dev);
|
||||
struct axon_ram_bank *bank = device->dev.platform_data;
|
||||
|
||||
BUG_ON(!bank);
|
||||
|
@ -90,7 +90,7 @@ static DEVICE_ATTR(ecc, S_IRUGO, axon_ram_sysfs_ecc, NULL);
|
|||
static irqreturn_t
|
||||
axon_ram_irq_handler(int irq, void *dev)
|
||||
{
|
||||
struct of_device *device = dev;
|
||||
struct platform_device *device = dev;
|
||||
struct axon_ram_bank *bank = device->dev.platform_data;
|
||||
|
||||
BUG_ON(!bank);
|
||||
|
@ -174,8 +174,8 @@ static const struct block_device_operations axon_ram_devops = {
|
|||
* axon_ram_probe - probe() method for platform driver
|
||||
* @device, @device_id: see of_platform_driver method
|
||||
*/
|
||||
static int
|
||||
axon_ram_probe(struct of_device *device, const struct of_device_id *device_id)
|
||||
static int axon_ram_probe(struct platform_device *device,
|
||||
const struct of_device_id *device_id)
|
||||
{
|
||||
static int axon_ram_bank_id = -1;
|
||||
struct axon_ram_bank *bank;
|
||||
|
@ -304,7 +304,7 @@ failed:
|
|||
* @device: see of_platform_driver method
|
||||
*/
|
||||
static int
|
||||
axon_ram_remove(struct of_device *device)
|
||||
axon_ram_remove(struct platform_device *device)
|
||||
{
|
||||
struct axon_ram_bank *bank = device->dev.platform_data;
|
||||
|
||||
|
|
|
@ -365,8 +365,8 @@ bcom_engine_cleanup(void)
|
|||
/* OF platform driver */
|
||||
/* ======================================================================== */
|
||||
|
||||
static int __devinit
|
||||
mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match)
|
||||
static int __devinit mpc52xx_bcom_probe(struct platform_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct device_node *ofn_sram;
|
||||
struct resource res_bcom;
|
||||
|
@ -461,8 +461,7 @@ error_ofput:
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
mpc52xx_bcom_remove(struct of_device *op)
|
||||
static int mpc52xx_bcom_remove(struct platform_device *op)
|
||||
{
|
||||
/* Clean up the engine */
|
||||
bcom_engine_cleanup();
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
* kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
|
|
|
@ -621,7 +621,6 @@ int cpm1_gpiochip_add16(struct device_node *np)
|
|||
{
|
||||
struct cpm1_gpio16_chip *cpm1_gc;
|
||||
struct of_mm_gpio_chip *mm_gc;
|
||||
struct of_gpio_chip *of_gc;
|
||||
struct gpio_chip *gc;
|
||||
|
||||
cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
|
||||
|
@ -631,11 +630,9 @@ int cpm1_gpiochip_add16(struct device_node *np)
|
|||
spin_lock_init(&cpm1_gc->lock);
|
||||
|
||||
mm_gc = &cpm1_gc->mm_gc;
|
||||
of_gc = &mm_gc->of_gc;
|
||||
gc = &of_gc->gc;
|
||||
gc = &mm_gc->gc;
|
||||
|
||||
mm_gc->save_regs = cpm1_gpio16_save_regs;
|
||||
of_gc->gpio_cells = 2;
|
||||
gc->ngpio = 16;
|
||||
gc->direction_input = cpm1_gpio16_dir_in;
|
||||
gc->direction_output = cpm1_gpio16_dir_out;
|
||||
|
@ -745,7 +742,6 @@ int cpm1_gpiochip_add32(struct device_node *np)
|
|||
{
|
||||
struct cpm1_gpio32_chip *cpm1_gc;
|
||||
struct of_mm_gpio_chip *mm_gc;
|
||||
struct of_gpio_chip *of_gc;
|
||||
struct gpio_chip *gc;
|
||||
|
||||
cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
|
||||
|
@ -755,11 +751,9 @@ int cpm1_gpiochip_add32(struct device_node *np)
|
|||
spin_lock_init(&cpm1_gc->lock);
|
||||
|
||||
mm_gc = &cpm1_gc->mm_gc;
|
||||
of_gc = &mm_gc->of_gc;
|
||||
gc = &of_gc->gc;
|
||||
gc = &mm_gc->gc;
|
||||
|
||||
mm_gc->save_regs = cpm1_gpio32_save_regs;
|
||||
of_gc->gpio_cells = 2;
|
||||
gc->ngpio = 32;
|
||||
gc->direction_input = cpm1_gpio32_dir_in;
|
||||
gc->direction_output = cpm1_gpio32_dir_out;
|
||||
|
|
|
@ -325,7 +325,6 @@ int cpm2_gpiochip_add32(struct device_node *np)
|
|||
{
|
||||
struct cpm2_gpio32_chip *cpm2_gc;
|
||||
struct of_mm_gpio_chip *mm_gc;
|
||||
struct of_gpio_chip *of_gc;
|
||||
struct gpio_chip *gc;
|
||||
|
||||
cpm2_gc = kzalloc(sizeof(*cpm2_gc), GFP_KERNEL);
|
||||
|
@ -335,11 +334,9 @@ int cpm2_gpiochip_add32(struct device_node *np)
|
|||
spin_lock_init(&cpm2_gc->lock);
|
||||
|
||||
mm_gc = &cpm2_gc->mm_gc;
|
||||
of_gc = &mm_gc->of_gc;
|
||||
gc = &of_gc->gc;
|
||||
gc = &mm_gc->gc;
|
||||
|
||||
mm_gc->save_regs = cpm2_gpio32_save_regs;
|
||||
of_gc->gpio_cells = 2;
|
||||
gc->ngpio = 32;
|
||||
gc->direction_input = cpm2_gpio32_dir_in;
|
||||
gc->direction_output = cpm2_gpio32_dir_out;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/io.h>
|
||||
|
|
|
@ -250,7 +250,7 @@ unlock:
|
|||
raw_spin_unlock(&desc->lock);
|
||||
}
|
||||
|
||||
static int fsl_of_msi_remove(struct of_device *ofdev)
|
||||
static int fsl_of_msi_remove(struct platform_device *ofdev)
|
||||
{
|
||||
struct fsl_msi *msi = ofdev->dev.platform_data;
|
||||
int virq, i;
|
||||
|
@ -274,7 +274,7 @@ static int fsl_of_msi_remove(struct of_device *ofdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit fsl_of_msi_probe(struct of_device *dev,
|
||||
static int __devinit fsl_of_msi_probe(struct platform_device *dev,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct fsl_msi *msi;
|
||||
|
|
|
@ -58,7 +58,8 @@ static struct platform_suspend_ops pmc_suspend_ops = {
|
|||
.enter = pmc_suspend_enter,
|
||||
};
|
||||
|
||||
static int pmc_probe(struct of_device *ofdev, const struct of_device_id *id)
|
||||
static int pmc_probe(struct platform_device *ofdev,
|
||||
const struct of_device_id *id)
|
||||
{
|
||||
pmc_regs = of_iomap(ofdev->dev.of_node, 0);
|
||||
if (!pmc_regs)
|
||||
|
|
|
@ -1338,7 +1338,7 @@ static inline void fsl_rio_info(struct device *dev, u32 ccsr)
|
|||
* master port with system-specific info, and registers the
|
||||
* master port with the RapidIO subsystem.
|
||||
*/
|
||||
int fsl_rio_setup(struct of_device *dev)
|
||||
int fsl_rio_setup(struct platform_device *dev)
|
||||
{
|
||||
struct rio_ops *ops;
|
||||
struct rio_mport *port;
|
||||
|
@ -1536,7 +1536,7 @@ err_ops:
|
|||
|
||||
/* The probe function for RapidIO peer-to-peer network.
|
||||
*/
|
||||
static int __devinit fsl_of_rio_rpn_probe(struct of_device *dev,
|
||||
static int __devinit fsl_of_rio_rpn_probe(struct platform_device *dev,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
int rc;
|
||||
|
|
|
@ -257,7 +257,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
|
|||
{
|
||||
struct mpc8xxx_gpio_chip *mpc8xxx_gc;
|
||||
struct of_mm_gpio_chip *mm_gc;
|
||||
struct of_gpio_chip *of_gc;
|
||||
struct gpio_chip *gc;
|
||||
unsigned hwirq;
|
||||
int ret;
|
||||
|
@ -271,11 +270,9 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
|
|||
spin_lock_init(&mpc8xxx_gc->lock);
|
||||
|
||||
mm_gc = &mpc8xxx_gc->mm_gc;
|
||||
of_gc = &mm_gc->of_gc;
|
||||
gc = &of_gc->gc;
|
||||
gc = &mm_gc->gc;
|
||||
|
||||
mm_gc->save_regs = mpc8xxx_gpio_save_regs;
|
||||
of_gc->gpio_cells = 2;
|
||||
gc->ngpio = MPC8XXX_GPIO_PINS;
|
||||
gc->direction_input = mpc8xxx_gpio_dir_in;
|
||||
gc->direction_output = mpc8xxx_gpio_dir_out;
|
||||
|
|
|
@ -20,12 +20,7 @@
|
|||
|
||||
#include <asm/prom.h>
|
||||
|
||||
/*
|
||||
* These functions provide the necessary setup for the mv64x60 drivers.
|
||||
* These drivers are unusual in that they work on both the MIPS and PowerPC
|
||||
* architectures. Because of that, the drivers do not support the normal
|
||||
* PowerPC of_platform_bus_type. They support platform_bus_type instead.
|
||||
*/
|
||||
/* These functions provide the necessary setup for the mv64x60 drivers. */
|
||||
|
||||
static struct of_device_id __initdata of_mv64x60_devices[] = {
|
||||
{ .compatible = "marvell,mv64306-devctrl", },
|
||||
|
|
|
@ -43,7 +43,7 @@ struct pmi_data {
|
|||
struct mutex msg_mutex;
|
||||
pmi_message_t msg;
|
||||
struct completion *completion;
|
||||
struct of_device *dev;
|
||||
struct platform_device *dev;
|
||||
int irq;
|
||||
u8 __iomem *pmi_reg;
|
||||
struct work_struct work;
|
||||
|
@ -121,7 +121,7 @@ static void pmi_notify_handlers(struct work_struct *work)
|
|||
spin_unlock(&data->handler_spinlock);
|
||||
}
|
||||
|
||||
static int pmi_of_probe(struct of_device *dev,
|
||||
static int pmi_of_probe(struct platform_device *dev,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct device_node *np = dev->dev.of_node;
|
||||
|
@ -185,7 +185,7 @@ out:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int pmi_of_remove(struct of_device *dev)
|
||||
static int pmi_of_remove(struct platform_device *dev)
|
||||
{
|
||||
struct pmi_handler *handler, *tmp;
|
||||
|
||||
|
|
|
@ -181,7 +181,6 @@ static int __init ppc4xx_add_gpiochips(void)
|
|||
int ret;
|
||||
struct ppc4xx_gpio_chip *ppc4xx_gc;
|
||||
struct of_mm_gpio_chip *mm_gc;
|
||||
struct of_gpio_chip *of_gc;
|
||||
struct gpio_chip *gc;
|
||||
|
||||
ppc4xx_gc = kzalloc(sizeof(*ppc4xx_gc), GFP_KERNEL);
|
||||
|
@ -193,10 +192,8 @@ static int __init ppc4xx_add_gpiochips(void)
|
|||
spin_lock_init(&ppc4xx_gc->lock);
|
||||
|
||||
mm_gc = &ppc4xx_gc->mm_gc;
|
||||
of_gc = &mm_gc->of_gc;
|
||||
gc = &of_gc->gc;
|
||||
gc = &mm_gc->gc;
|
||||
|
||||
of_gc->gpio_cells = 2;
|
||||
gc->ngpio = 32;
|
||||
gc->direction_input = ppc4xx_gpio_dir_in;
|
||||
gc->direction_output = ppc4xx_gpio_dir_out;
|
||||
|
|
|
@ -138,8 +138,8 @@ struct qe_pin {
|
|||
struct qe_pin *qe_pin_request(struct device_node *np, int index)
|
||||
{
|
||||
struct qe_pin *qe_pin;
|
||||
struct device_node *gc;
|
||||
struct of_gpio_chip *of_gc = NULL;
|
||||
struct device_node *gpio_np;
|
||||
struct gpio_chip *gc;
|
||||
struct of_mm_gpio_chip *mm_gc;
|
||||
struct qe_gpio_chip *qe_gc;
|
||||
int err;
|
||||
|
@ -155,40 +155,40 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index)
|
|||
}
|
||||
|
||||
err = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index,
|
||||
&gc, &gpio_spec);
|
||||
&gpio_np, &gpio_spec);
|
||||
if (err) {
|
||||
pr_debug("%s: can't parse gpios property\n", __func__);
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (!of_device_is_compatible(gc, "fsl,mpc8323-qe-pario-bank")) {
|
||||
if (!of_device_is_compatible(gpio_np, "fsl,mpc8323-qe-pario-bank")) {
|
||||
pr_debug("%s: tried to get a non-qe pin\n", __func__);
|
||||
err = -EINVAL;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
of_gc = gc->data;
|
||||
if (!of_gc) {
|
||||
gc = of_node_to_gpiochip(gpio_np);
|
||||
if (!gc) {
|
||||
pr_debug("%s: gpio controller %s isn't registered\n",
|
||||
np->full_name, gc->full_name);
|
||||
np->full_name, gpio_np->full_name);
|
||||
err = -ENODEV;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
gpio_cells = of_get_property(gc, "#gpio-cells", &size);
|
||||
gpio_cells = of_get_property(gpio_np, "#gpio-cells", &size);
|
||||
if (!gpio_cells || size != sizeof(*gpio_cells) ||
|
||||
*gpio_cells != of_gc->gpio_cells) {
|
||||
*gpio_cells != gc->of_gpio_n_cells) {
|
||||
pr_debug("%s: wrong #gpio-cells for %s\n",
|
||||
np->full_name, gc->full_name);
|
||||
np->full_name, gpio_np->full_name);
|
||||
err = -EINVAL;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
err = of_gc->xlate(of_gc, np, gpio_spec, NULL);
|
||||
err = gc->of_xlate(gc, np, gpio_spec, NULL);
|
||||
if (err < 0)
|
||||
goto err1;
|
||||
|
||||
mm_gc = to_of_mm_gpio_chip(&of_gc->gc);
|
||||
mm_gc = to_of_mm_gpio_chip(gc);
|
||||
qe_gc = to_qe_gpio_chip(mm_gc);
|
||||
|
||||
spin_lock_irqsave(&qe_gc->lock, flags);
|
||||
|
@ -206,7 +206,7 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index)
|
|||
if (!err)
|
||||
return qe_pin;
|
||||
err1:
|
||||
of_node_put(gc);
|
||||
of_node_put(gpio_np);
|
||||
err0:
|
||||
kfree(qe_pin);
|
||||
pr_debug("%s failed with status %d\n", __func__, err);
|
||||
|
@ -307,7 +307,6 @@ static int __init qe_add_gpiochips(void)
|
|||
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);
|
||||
|
@ -319,11 +318,9 @@ static int __init qe_add_gpiochips(void)
|
|||
spin_lock_init(&qe_gc->lock);
|
||||
|
||||
mm_gc = &qe_gc->mm_gc;
|
||||
of_gc = &mm_gc->of_gc;
|
||||
gc = &of_gc->gc;
|
||||
gc = &mm_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;
|
||||
|
|
|
@ -651,14 +651,15 @@ unsigned int qe_get_num_of_snums(void)
|
|||
EXPORT_SYMBOL(qe_get_num_of_snums);
|
||||
|
||||
#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx)
|
||||
static int qe_resume(struct of_device *ofdev)
|
||||
static int qe_resume(struct platform_device *ofdev)
|
||||
{
|
||||
if (!qe_alive_during_sleep())
|
||||
qe_reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qe_probe(struct of_device *ofdev, const struct of_device_id *id)
|
||||
static int qe_probe(struct platform_device *ofdev,
|
||||
const struct of_device_id *id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -91,7 +91,6 @@ static int __init u8_simple_gpiochip_add(struct device_node *np)
|
|||
int ret;
|
||||
struct u8_gpio_chip *u8_gc;
|
||||
struct of_mm_gpio_chip *mm_gc;
|
||||
struct of_gpio_chip *of_gc;
|
||||
struct gpio_chip *gc;
|
||||
|
||||
u8_gc = kzalloc(sizeof(*u8_gc), GFP_KERNEL);
|
||||
|
@ -101,11 +100,9 @@ static int __init u8_simple_gpiochip_add(struct device_node *np)
|
|||
spin_lock_init(&u8_gc->lock);
|
||||
|
||||
mm_gc = &u8_gc->mm_gc;
|
||||
of_gc = &mm_gc->of_gc;
|
||||
gc = &of_gc->gc;
|
||||
gc = &mm_gc->gc;
|
||||
|
||||
mm_gc->save_regs = u8_gpio_save_regs;
|
||||
of_gc->gpio_cells = 2;
|
||||
gc->ngpio = 8;
|
||||
gc->direction_input = u8_gpio_dir_in;
|
||||
gc->direction_output = u8_gpio_dir_out;
|
||||
|
|
|
@ -18,6 +18,7 @@ config 64BIT
|
|||
config SPARC
|
||||
bool
|
||||
default y
|
||||
select OF
|
||||
select HAVE_IDE
|
||||
select HAVE_OPROFILE
|
||||
select HAVE_ARCH_KGDB if !SMP || SPARC64
|
||||
|
@ -148,9 +149,6 @@ config GENERIC_GPIO
|
|||
config ARCH_NO_VIRT_TO_BUS
|
||||
def_bool y
|
||||
|
||||
config OF
|
||||
def_bool y
|
||||
|
||||
config ARCH_SUPPORTS_DEBUG_PAGEALLOC
|
||||
def_bool y if SPARC64
|
||||
|
||||
|
|
|
@ -6,18 +6,25 @@
|
|||
#ifndef _ASM_SPARC_DEVICE_H
|
||||
#define _ASM_SPARC_DEVICE_H
|
||||
|
||||
#include <asm/openprom.h>
|
||||
|
||||
struct device_node;
|
||||
struct of_device;
|
||||
struct platform_device;
|
||||
|
||||
struct dev_archdata {
|
||||
void *iommu;
|
||||
void *stc;
|
||||
void *host_controller;
|
||||
struct of_device *op;
|
||||
struct platform_device *op;
|
||||
int numa_node;
|
||||
};
|
||||
|
||||
extern void of_propagate_archdata(struct platform_device *bus);
|
||||
|
||||
struct pdev_archdata {
|
||||
struct resource resource[PROMREG_MAX];
|
||||
unsigned int irqs[PROMINTR_MAX];
|
||||
int num_irqs;
|
||||
};
|
||||
|
||||
#endif /* _ASM_SPARC_DEVICE_H */
|
||||
|
|
|
@ -43,7 +43,7 @@ struct sun_flpy_controller {
|
|||
/* You'll only ever find one controller on an Ultra anyways. */
|
||||
static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1;
|
||||
unsigned long fdc_status;
|
||||
static struct of_device *floppy_op = NULL;
|
||||
static struct platform_device *floppy_op = NULL;
|
||||
|
||||
struct sun_floppy_ops {
|
||||
unsigned char (*fd_inb) (unsigned long port);
|
||||
|
@ -548,7 +548,7 @@ static unsigned long __init sun_floppy_init(void)
|
|||
{
|
||||
static int initialized = 0;
|
||||
struct device_node *dp;
|
||||
struct of_device *op;
|
||||
struct platform_device *op;
|
||||
const char *prop;
|
||||
char state[128];
|
||||
|
||||
|
@ -567,7 +567,7 @@ static unsigned long __init sun_floppy_init(void)
|
|||
}
|
||||
if (op) {
|
||||
floppy_op = op;
|
||||
FLOPPY_IRQ = op->irqs[0];
|
||||
FLOPPY_IRQ = op->archdata.irqs[0];
|
||||
} else {
|
||||
struct device_node *ebus_dp;
|
||||
void __iomem *auxio_reg;
|
||||
|
@ -593,7 +593,7 @@ static unsigned long __init sun_floppy_init(void)
|
|||
if (state_prop && !strncmp(state_prop, "disabled", 8))
|
||||
return 0;
|
||||
|
||||
FLOPPY_IRQ = op->irqs[0];
|
||||
FLOPPY_IRQ = op->archdata.irqs[0];
|
||||
|
||||
/* Make sure the high density bit is set, some systems
|
||||
* (most notably Ultra5/Ultra10) come up with it clear.
|
||||
|
@ -661,7 +661,7 @@ static unsigned long __init sun_floppy_init(void)
|
|||
config = 0;
|
||||
for (dp = ebus_dp->child; dp; dp = dp->sibling) {
|
||||
if (!strcmp(dp->name, "ecpp")) {
|
||||
struct of_device *ecpp_op;
|
||||
struct platform_device *ecpp_op;
|
||||
|
||||
ecpp_op = of_find_device_by_node(dp);
|
||||
if (ecpp_op)
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
#ifndef _ASM_SPARC_OF_DEVICE_H
|
||||
#define _ASM_SPARC_OF_DEVICE_H
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <asm/openprom.h>
|
||||
|
||||
/*
|
||||
* The of_device is a kind of "base class" that is a superset of
|
||||
* struct device for use by devices attached to an OF node and
|
||||
* probed using OF properties.
|
||||
*/
|
||||
struct of_device
|
||||
{
|
||||
struct device dev;
|
||||
struct resource resource[PROMREG_MAX];
|
||||
unsigned int irqs[PROMINTR_MAX];
|
||||
int num_irqs;
|
||||
|
||||
void *sysdata;
|
||||
|
||||
int slot;
|
||||
int portid;
|
||||
int clock_freq;
|
||||
};
|
||||
|
||||
extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
|
||||
extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
|
||||
|
||||
extern void of_propagate_archdata(struct of_device *bus);
|
||||
|
||||
/* This is just here during the transition */
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _ASM_SPARC_OF_DEVICE_H */
|
|
@ -1,18 +0,0 @@
|
|||
#ifndef ___ASM_SPARC_OF_PLATFORM_H
|
||||
#define ___ASM_SPARC_OF_PLATFORM_H
|
||||
/*
|
||||
* Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
|
||||
* <benh@kernel.crashing.org>
|
||||
* Modified for Sparc by merging parts of asm/of_device.h
|
||||
* by Stephen Rothwell
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#define of_bus_type of_platform_bus_type /* for compatibility */
|
||||
|
||||
#endif
|
|
@ -103,7 +103,7 @@ static inline unsigned int get_dma_residue(unsigned int dmanr)
|
|||
return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info);
|
||||
}
|
||||
|
||||
static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id *match)
|
||||
static int __devinit ecpp_probe(struct platform_device *op, const struct of_device_id *match)
|
||||
{
|
||||
unsigned long base = op->resource[0].start;
|
||||
unsigned long config = op->resource[1].start;
|
||||
|
@ -116,7 +116,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id
|
|||
parent = op->dev.of_node->parent;
|
||||
if (!strcmp(parent->name, "dma")) {
|
||||
p = parport_pc_probe_port(base, base + 0x400,
|
||||
op->irqs[0], PARPORT_DMA_NOFIFO,
|
||||
op->archdata.irqs[0], PARPORT_DMA_NOFIFO,
|
||||
op->dev.parent->parent, 0);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
@ -166,7 +166,7 @@ static int __devinit ecpp_probe(struct of_device *op, const struct of_device_id
|
|||
0, PTR_LPT_REG_DIR);
|
||||
|
||||
p = parport_pc_probe_port(base, base + 0x400,
|
||||
op->irqs[0],
|
||||
op->archdata.irqs[0],
|
||||
slot,
|
||||
op->dev.parent,
|
||||
0);
|
||||
|
@ -192,7 +192,7 @@ out_err:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int __devexit ecpp_remove(struct of_device *op)
|
||||
static int __devexit ecpp_remove(struct platform_device *op)
|
||||
{
|
||||
struct parport *p = dev_get_drvdata(&op->dev);
|
||||
int slot = p->dma;
|
||||
|
@ -243,9 +243,7 @@ static struct of_platform_driver ecpp_driver = {
|
|||
|
||||
static int parport_pc_find_nonpci_ports(int autoirq, int autodma)
|
||||
{
|
||||
of_register_driver(&ecpp_driver, &of_bus_type);
|
||||
|
||||
return 0;
|
||||
return of_register_platform_driver(&ecpp_driver);
|
||||
}
|
||||
|
||||
#endif /* !(_ASM_SPARC64_PARPORT_H */
|
||||
|
|
|
@ -43,20 +43,22 @@ extern int of_getintprop_default(struct device_node *np,
|
|||
extern int of_find_in_proplist(const char *list, const char *match, int len);
|
||||
#ifdef CONFIG_NUMA
|
||||
extern int of_node_to_nid(struct device_node *dp);
|
||||
#else
|
||||
#define of_node_to_nid(dp) (-1)
|
||||
#define of_node_to_nid of_node_to_nid
|
||||
#endif
|
||||
|
||||
extern void prom_build_devicetree(void);
|
||||
extern void of_populate_present_mask(void);
|
||||
extern void of_fill_in_cpu_data(void);
|
||||
|
||||
struct resource;
|
||||
extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
|
||||
extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
|
||||
|
||||
/* These routines are here to provide compatibility with how powerpc
|
||||
* handles IRQ mapping for OF device nodes. We precompute and permanently
|
||||
* register them in the of_device objects, whereas powerpc computes them
|
||||
* register them in the platform_device objects, whereas powerpc computes them
|
||||
* on request.
|
||||
*/
|
||||
extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
|
||||
static inline void irq_dispose_mapping(unsigned int virq)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ static void apc_swift_idle(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline void apc_free(struct of_device *op)
|
||||
static inline void apc_free(struct platform_device *op)
|
||||
{
|
||||
of_iounmap(&op->resource[0], regs, resource_size(&op->resource[0]));
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ static const struct file_operations apc_fops = {
|
|||
|
||||
static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops };
|
||||
|
||||
static int __devinit apc_probe(struct of_device *op,
|
||||
static int __devinit apc_probe(struct platform_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
int err;
|
||||
|
@ -184,7 +184,7 @@ static struct of_platform_driver apc_driver = {
|
|||
|
||||
static int __init apc_init(void)
|
||||
{
|
||||
return of_register_driver(&apc_driver, &of_bus_type);
|
||||
return of_register_platform_driver(&apc_driver);
|
||||
}
|
||||
|
||||
/* This driver is not critical to the boot process
|
||||
|
|
|
@ -102,7 +102,8 @@ static struct of_device_id __initdata auxio_match[] = {
|
|||
|
||||
MODULE_DEVICE_TABLE(of, auxio_match);
|
||||
|
||||
static int __devinit auxio_probe(struct of_device *dev, const struct of_device_id *match)
|
||||
static int __devinit auxio_probe(struct platform_device *dev,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct device_node *dp = dev->dev.of_node;
|
||||
unsigned long size;
|
||||
|
@ -142,7 +143,7 @@ static struct of_platform_driver auxio_driver = {
|
|||
|
||||
static int __init auxio_init(void)
|
||||
{
|
||||
return of_register_driver(&auxio_driver, &of_platform_bus_type);
|
||||
return of_register_platform_driver(&auxio_driver);
|
||||
}
|
||||
|
||||
/* Must be after subsys_initcall() so that busses are probed. Must
|
||||
|
|
|
@ -59,7 +59,7 @@ static int __devinit clock_board_calc_nslots(struct clock_board *p)
|
|||
}
|
||||
}
|
||||
|
||||
static int __devinit clock_board_probe(struct of_device *op,
|
||||
static int __devinit clock_board_probe(struct platform_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct clock_board *p = kzalloc(sizeof(*p), GFP_KERNEL);
|
||||
|
@ -157,7 +157,7 @@ static struct of_platform_driver clock_board_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __devinit fhc_probe(struct of_device *op,
|
||||
static int __devinit fhc_probe(struct platform_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct fhc *p = kzalloc(sizeof(*p), GFP_KERNEL);
|
||||
|
@ -265,8 +265,8 @@ static struct of_platform_driver fhc_driver = {
|
|||
|
||||
static int __init sunfire_init(void)
|
||||
{
|
||||
(void) of_register_driver(&fhc_driver, &of_platform_bus_type);
|
||||
(void) of_register_driver(&clock_board_driver, &of_platform_bus_type);
|
||||
(void) of_register_platform_driver(&fhc_driver);
|
||||
(void) of_register_platform_driver(&clock_board_driver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -392,7 +392,7 @@ static void __devinit jbusmc_construct_dimm_groups(struct jbusmc *p,
|
|||
}
|
||||
}
|
||||
|
||||
static int __devinit jbusmc_probe(struct of_device *op,
|
||||
static int __devinit jbusmc_probe(struct platform_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
const struct linux_prom64_registers *mem_regs;
|
||||
|
@ -690,7 +690,7 @@ static void chmc_fetch_decode_regs(struct chmc *p)
|
|||
chmc_read_mcreg(p, CHMCTRL_DECODE4));
|
||||
}
|
||||
|
||||
static int __devinit chmc_probe(struct of_device *op,
|
||||
static int __devinit chmc_probe(struct platform_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct device_node *dp = op->dev.of_node;
|
||||
|
@ -765,7 +765,7 @@ out_free:
|
|||
goto out;
|
||||
}
|
||||
|
||||
static int __devinit us3mc_probe(struct of_device *op,
|
||||
static int __devinit us3mc_probe(struct platform_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
if (mc_type == MC_TYPE_SAFARI)
|
||||
|
@ -775,21 +775,21 @@ static int __devinit us3mc_probe(struct of_device *op,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void __devexit chmc_destroy(struct of_device *op, struct chmc *p)
|
||||
static void __devexit chmc_destroy(struct platform_device *op, struct chmc *p)
|
||||
{
|
||||
list_del(&p->list);
|
||||
of_iounmap(&op->resource[0], p->regs, 0x48);
|
||||
kfree(p);
|
||||
}
|
||||
|
||||
static void __devexit jbusmc_destroy(struct of_device *op, struct jbusmc *p)
|
||||
static void __devexit jbusmc_destroy(struct platform_device *op, struct jbusmc *p)
|
||||
{
|
||||
mc_list_del(&p->list);
|
||||
of_iounmap(&op->resource[0], p->regs, JBUSMC_REGS_SIZE);
|
||||
kfree(p);
|
||||
}
|
||||
|
||||
static int __devexit us3mc_remove(struct of_device *op)
|
||||
static int __devexit us3mc_remove(struct platform_device *op)
|
||||
{
|
||||
void *p = dev_get_drvdata(&op->dev);
|
||||
|
||||
|
@ -848,7 +848,7 @@ static int __init us3mc_init(void)
|
|||
ret = register_dimm_printer(us3mc_dimm_printer);
|
||||
|
||||
if (!ret) {
|
||||
ret = of_register_driver(&us3mc_driver, &of_bus_type);
|
||||
ret = of_register_platform_driver(&us3mc_driver);
|
||||
if (ret)
|
||||
unregister_dimm_printer(us3mc_dimm_printer);
|
||||
}
|
||||
|
@ -859,7 +859,7 @@ static void __exit us3mc_cleanup(void)
|
|||
{
|
||||
if (us3mc_platform()) {
|
||||
unregister_dimm_printer(us3mc_dimm_printer);
|
||||
of_unregister_driver(&us3mc_driver);
|
||||
of_unregister_platform_driver(&us3mc_driver);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -253,7 +253,7 @@ EXPORT_SYMBOL(sbus_set_sbus64);
|
|||
static void *sbus_alloc_coherent(struct device *dev, size_t len,
|
||||
dma_addr_t *dma_addrp, gfp_t gfp)
|
||||
{
|
||||
struct of_device *op = to_of_device(dev);
|
||||
struct platform_device *op = to_platform_device(dev);
|
||||
unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK;
|
||||
unsigned long va;
|
||||
struct resource *res;
|
||||
|
|
|
@ -241,10 +241,10 @@ static int __init use_1to1_mapping(struct device_node *pp)
|
|||
|
||||
static int of_resource_verbose;
|
||||
|
||||
static void __init build_device_resources(struct of_device *op,
|
||||
static void __init build_device_resources(struct platform_device *op,
|
||||
struct device *parent)
|
||||
{
|
||||
struct of_device *p_op;
|
||||
struct platform_device *p_op;
|
||||
struct of_bus *bus;
|
||||
int na, ns;
|
||||
int index, num_reg;
|
||||
|
@ -253,7 +253,7 @@ static void __init build_device_resources(struct of_device *op,
|
|||
if (!parent)
|
||||
return;
|
||||
|
||||
p_op = to_of_device(parent);
|
||||
p_op = to_platform_device(parent);
|
||||
bus = of_match_bus(p_op->dev.of_node);
|
||||
bus->count_cells(op->dev.of_node, &na, &ns);
|
||||
|
||||
|
@ -267,6 +267,8 @@ static void __init build_device_resources(struct of_device *op,
|
|||
/* Conver to num-entries. */
|
||||
num_reg /= na + ns;
|
||||
|
||||
op->resource = op->archdata.resource;
|
||||
op->num_resources = num_reg;
|
||||
for (index = 0; index < num_reg; index++) {
|
||||
struct resource *r = &op->resource[index];
|
||||
u32 addr[OF_MAX_ADDR_CELLS];
|
||||
|
@ -333,10 +335,10 @@ static void __init build_device_resources(struct of_device *op,
|
|||
}
|
||||
}
|
||||
|
||||
static struct of_device * __init scan_one_device(struct device_node *dp,
|
||||
static struct platform_device * __init scan_one_device(struct device_node *dp,
|
||||
struct device *parent)
|
||||
{
|
||||
struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
|
||||
struct platform_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
|
||||
const struct linux_prom_irqs *intr;
|
||||
struct dev_archdata *sd;
|
||||
int len, i;
|
||||
|
@ -349,27 +351,21 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
|
|||
|
||||
op->dev.of_node = dp;
|
||||
|
||||
op->clock_freq = of_getintprop_default(dp, "clock-frequency",
|
||||
(25*1000*1000));
|
||||
op->portid = of_getintprop_default(dp, "upa-portid", -1);
|
||||
if (op->portid == -1)
|
||||
op->portid = of_getintprop_default(dp, "portid", -1);
|
||||
|
||||
intr = of_get_property(dp, "intr", &len);
|
||||
if (intr) {
|
||||
op->num_irqs = len / sizeof(struct linux_prom_irqs);
|
||||
for (i = 0; i < op->num_irqs; i++)
|
||||
op->irqs[i] = intr[i].pri;
|
||||
op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs);
|
||||
for (i = 0; i < op->archdata.num_irqs; i++)
|
||||
op->archdata.irqs[i] = intr[i].pri;
|
||||
} else {
|
||||
const unsigned int *irq =
|
||||
of_get_property(dp, "interrupts", &len);
|
||||
|
||||
if (irq) {
|
||||
op->num_irqs = len / sizeof(unsigned int);
|
||||
for (i = 0; i < op->num_irqs; i++)
|
||||
op->irqs[i] = irq[i];
|
||||
op->archdata.num_irqs = len / sizeof(unsigned int);
|
||||
for (i = 0; i < op->archdata.num_irqs; i++)
|
||||
op->archdata.irqs[i] = irq[i];
|
||||
} else {
|
||||
op->num_irqs = 0;
|
||||
op->archdata.num_irqs = 0;
|
||||
}
|
||||
}
|
||||
if (sparc_cpu_model == sun4d) {
|
||||
|
@ -411,8 +407,8 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
|
|||
goto build_resources;
|
||||
}
|
||||
|
||||
for (i = 0; i < op->num_irqs; i++) {
|
||||
int this_irq = op->irqs[i];
|
||||
for (i = 0; i < op->archdata.num_irqs; i++) {
|
||||
int this_irq = op->archdata.irqs[i];
|
||||
int sbusl = pil_to_sbus[this_irq];
|
||||
|
||||
if (sbusl)
|
||||
|
@ -420,7 +416,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
|
|||
(sbusl << 2) +
|
||||
slot);
|
||||
|
||||
op->irqs[i] = this_irq;
|
||||
op->archdata.irqs[i] = this_irq;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,7 +424,7 @@ build_resources:
|
|||
build_device_resources(op, parent);
|
||||
|
||||
op->dev.parent = parent;
|
||||
op->dev.bus = &of_platform_bus_type;
|
||||
op->dev.bus = &platform_bus_type;
|
||||
if (!parent)
|
||||
dev_set_name(&op->dev, "root");
|
||||
else
|
||||
|
@ -447,7 +443,7 @@ build_resources:
|
|||
static void __init scan_tree(struct device_node *dp, struct device *parent)
|
||||
{
|
||||
while (dp) {
|
||||
struct of_device *op = scan_one_device(dp, parent);
|
||||
struct platform_device *op = scan_one_device(dp, parent);
|
||||
|
||||
if (op)
|
||||
scan_tree(dp->child, &op->dev);
|
||||
|
@ -456,30 +452,19 @@ static void __init scan_tree(struct device_node *dp, struct device *parent)
|
|||
}
|
||||
}
|
||||
|
||||
static void __init scan_of_devices(void)
|
||||
static int __init scan_of_devices(void)
|
||||
{
|
||||
struct device_node *root = of_find_node_by_path("/");
|
||||
struct of_device *parent;
|
||||
struct platform_device *parent;
|
||||
|
||||
parent = scan_one_device(root, NULL);
|
||||
if (!parent)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
scan_tree(root->child, &parent->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init of_bus_driver_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = of_bus_type_init(&of_platform_bus_type, "of");
|
||||
if (!err)
|
||||
scan_of_devices();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
postcore_initcall(of_bus_driver_init);
|
||||
postcore_initcall(scan_of_devices);
|
||||
|
||||
static int __init of_debug(char *str)
|
||||
{
|
||||
|
|
|
@ -310,10 +310,10 @@ static int __init use_1to1_mapping(struct device_node *pp)
|
|||
|
||||
static int of_resource_verbose;
|
||||
|
||||
static void __init build_device_resources(struct of_device *op,
|
||||
static void __init build_device_resources(struct platform_device *op,
|
||||
struct device *parent)
|
||||
{
|
||||
struct of_device *p_op;
|
||||
struct platform_device *p_op;
|
||||
struct of_bus *bus;
|
||||
int na, ns;
|
||||
int index, num_reg;
|
||||
|
@ -322,7 +322,7 @@ static void __init build_device_resources(struct of_device *op,
|
|||
if (!parent)
|
||||
return;
|
||||
|
||||
p_op = to_of_device(parent);
|
||||
p_op = to_platform_device(parent);
|
||||
bus = of_match_bus(p_op->dev.of_node);
|
||||
bus->count_cells(op->dev.of_node, &na, &ns);
|
||||
|
||||
|
@ -344,6 +344,8 @@ static void __init build_device_resources(struct of_device *op,
|
|||
num_reg = PROMREG_MAX;
|
||||
}
|
||||
|
||||
op->resource = op->archdata.resource;
|
||||
op->num_resources = num_reg;
|
||||
for (index = 0; index < num_reg; index++) {
|
||||
struct resource *r = &op->resource[index];
|
||||
u32 addr[OF_MAX_ADDR_CELLS];
|
||||
|
@ -526,7 +528,7 @@ static unsigned int __init pci_irq_swizzle(struct device_node *dp,
|
|||
|
||||
static int of_irq_verbose;
|
||||
|
||||
static unsigned int __init build_one_device_irq(struct of_device *op,
|
||||
static unsigned int __init build_one_device_irq(struct platform_device *op,
|
||||
struct device *parent,
|
||||
unsigned int irq)
|
||||
{
|
||||
|
@ -628,10 +630,10 @@ out:
|
|||
return irq;
|
||||
}
|
||||
|
||||
static struct of_device * __init scan_one_device(struct device_node *dp,
|
||||
static struct platform_device * __init scan_one_device(struct device_node *dp,
|
||||
struct device *parent)
|
||||
{
|
||||
struct of_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
|
||||
struct platform_device *op = kzalloc(sizeof(*op), GFP_KERNEL);
|
||||
const unsigned int *irq;
|
||||
struct dev_archdata *sd;
|
||||
int len, i;
|
||||
|
@ -644,34 +646,28 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
|
|||
|
||||
op->dev.of_node = dp;
|
||||
|
||||
op->clock_freq = of_getintprop_default(dp, "clock-frequency",
|
||||
(25*1000*1000));
|
||||
op->portid = of_getintprop_default(dp, "upa-portid", -1);
|
||||
if (op->portid == -1)
|
||||
op->portid = of_getintprop_default(dp, "portid", -1);
|
||||
|
||||
irq = of_get_property(dp, "interrupts", &len);
|
||||
if (irq) {
|
||||
op->num_irqs = len / 4;
|
||||
op->archdata.num_irqs = len / 4;
|
||||
|
||||
/* Prevent overrunning the op->irqs[] array. */
|
||||
if (op->num_irqs > PROMINTR_MAX) {
|
||||
if (op->archdata.num_irqs > PROMINTR_MAX) {
|
||||
printk(KERN_WARNING "%s: Too many irqs (%d), "
|
||||
"limiting to %d.\n",
|
||||
dp->full_name, op->num_irqs, PROMINTR_MAX);
|
||||
op->num_irqs = PROMINTR_MAX;
|
||||
dp->full_name, op->archdata.num_irqs, PROMINTR_MAX);
|
||||
op->archdata.num_irqs = PROMINTR_MAX;
|
||||
}
|
||||
memcpy(op->irqs, irq, op->num_irqs * 4);
|
||||
memcpy(op->archdata.irqs, irq, op->archdata.num_irqs * 4);
|
||||
} else {
|
||||
op->num_irqs = 0;
|
||||
op->archdata.num_irqs = 0;
|
||||
}
|
||||
|
||||
build_device_resources(op, parent);
|
||||
for (i = 0; i < op->num_irqs; i++)
|
||||
op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]);
|
||||
for (i = 0; i < op->archdata.num_irqs; i++)
|
||||
op->archdata.irqs[i] = build_one_device_irq(op, parent, op->archdata.irqs[i]);
|
||||
|
||||
op->dev.parent = parent;
|
||||
op->dev.bus = &of_platform_bus_type;
|
||||
op->dev.bus = &platform_bus_type;
|
||||
if (!parent)
|
||||
dev_set_name(&op->dev, "root");
|
||||
else
|
||||
|
@ -690,7 +686,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
|
|||
static void __init scan_tree(struct device_node *dp, struct device *parent)
|
||||
{
|
||||
while (dp) {
|
||||
struct of_device *op = scan_one_device(dp, parent);
|
||||
struct platform_device *op = scan_one_device(dp, parent);
|
||||
|
||||
if (op)
|
||||
scan_tree(dp->child, &op->dev);
|
||||
|
@ -699,30 +695,19 @@ static void __init scan_tree(struct device_node *dp, struct device *parent)
|
|||
}
|
||||
}
|
||||
|
||||
static void __init scan_of_devices(void)
|
||||
static int __init scan_of_devices(void)
|
||||
{
|
||||
struct device_node *root = of_find_node_by_path("/");
|
||||
struct of_device *parent;
|
||||
struct platform_device *parent;
|
||||
|
||||
parent = scan_one_device(root, NULL);
|
||||
if (!parent)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
scan_tree(root->child, &parent->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init of_bus_driver_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = of_bus_type_init(&of_platform_bus_type, "of");
|
||||
if (!err)
|
||||
scan_of_devices();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
postcore_initcall(of_bus_driver_init);
|
||||
postcore_initcall(scan_of_devices);
|
||||
|
||||
static int __init of_debug(char *str)
|
||||
{
|
||||
|
|
|
@ -11,48 +11,28 @@
|
|||
|
||||
#include "of_device_common.h"
|
||||
|
||||
static int node_match(struct device *dev, void *data)
|
||||
{
|
||||
struct of_device *op = to_of_device(dev);
|
||||
struct device_node *dp = data;
|
||||
|
||||
return (op->dev.of_node == dp);
|
||||
}
|
||||
|
||||
struct of_device *of_find_device_by_node(struct device_node *dp)
|
||||
{
|
||||
struct device *dev = bus_find_device(&of_platform_bus_type, NULL,
|
||||
dp, node_match);
|
||||
|
||||
if (dev)
|
||||
return to_of_device(dev);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(of_find_device_by_node);
|
||||
|
||||
unsigned int irq_of_parse_and_map(struct device_node *node, int index)
|
||||
{
|
||||
struct of_device *op = of_find_device_by_node(node);
|
||||
struct platform_device *op = of_find_device_by_node(node);
|
||||
|
||||
if (!op || index >= op->num_irqs)
|
||||
if (!op || index >= op->archdata.num_irqs)
|
||||
return 0;
|
||||
|
||||
return op->irqs[index];
|
||||
return op->archdata.irqs[index];
|
||||
}
|
||||
EXPORT_SYMBOL(irq_of_parse_and_map);
|
||||
|
||||
/* Take the archdata values for IOMMU, STC, and HOSTDATA found in
|
||||
* BUS and propagate to all child of_device objects.
|
||||
* BUS and propagate to all child platform_device objects.
|
||||
*/
|
||||
void of_propagate_archdata(struct of_device *bus)
|
||||
void of_propagate_archdata(struct platform_device *bus)
|
||||
{
|
||||
struct dev_archdata *bus_sd = &bus->dev.archdata;
|
||||
struct device_node *bus_dp = bus->dev.of_node;
|
||||
struct device_node *dp;
|
||||
|
||||
for (dp = bus_dp->child; dp; dp = dp->sibling) {
|
||||
struct of_device *op = of_find_device_by_node(dp);
|
||||
struct platform_device *op = of_find_device_by_node(dp);
|
||||
|
||||
op->dev.archdata.iommu = bus_sd->iommu;
|
||||
op->dev.archdata.stc = bus_sd->stc;
|
||||
|
@ -64,9 +44,6 @@ void of_propagate_archdata(struct of_device *bus)
|
|||
}
|
||||
}
|
||||
|
||||
struct bus_type of_platform_bus_type;
|
||||
EXPORT_SYMBOL(of_platform_bus_type);
|
||||
|
||||
static void get_cells(struct device_node *dp, int *addrc, int *sizec)
|
||||
{
|
||||
if (addrc)
|
||||
|
|
|
@ -198,7 +198,7 @@ static unsigned long pci_parse_of_flags(u32 addr0)
|
|||
* into physical address resources, we only have to figure out the register
|
||||
* mapping.
|
||||
*/
|
||||
static void pci_parse_of_addrs(struct of_device *op,
|
||||
static void pci_parse_of_addrs(struct platform_device *op,
|
||||
struct device_node *node,
|
||||
struct pci_dev *dev)
|
||||
{
|
||||
|
@ -248,7 +248,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
|
|||
{
|
||||
struct dev_archdata *sd;
|
||||
struct pci_slot *slot;
|
||||
struct of_device *op;
|
||||
struct platform_device *op;
|
||||
struct pci_dev *dev;
|
||||
const char *type;
|
||||
u32 class;
|
||||
|
@ -340,7 +340,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
|
|||
dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
|
||||
dev->rom_base_reg = PCI_ROM_ADDRESS;
|
||||
|
||||
dev->irq = sd->op->irqs[0];
|
||||
dev->irq = sd->op->archdata.irqs[0];
|
||||
if (dev->irq == 0xffffffff)
|
||||
dev->irq = PCI_IRQ_NONE;
|
||||
}
|
||||
|
|
|
@ -410,7 +410,7 @@ static void pci_fire_hw_init(struct pci_pbm_info *pbm)
|
|||
}
|
||||
|
||||
static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm,
|
||||
struct of_device *op, u32 portid)
|
||||
struct platform_device *op, u32 portid)
|
||||
{
|
||||
const struct linux_prom64_registers *regs;
|
||||
struct device_node *dp = op->dev.of_node;
|
||||
|
@ -455,7 +455,7 @@ static int __devinit pci_fire_pbm_init(struct pci_pbm_info *pbm,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit fire_probe(struct of_device *op,
|
||||
static int __devinit fire_probe(struct platform_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
struct device_node *dp = op->dev.of_node;
|
||||
|
@ -518,7 +518,7 @@ static struct of_platform_driver fire_driver = {
|
|||
|
||||
static int __init fire_init(void)
|
||||
{
|
||||
return of_register_driver(&fire_driver, &of_bus_type);
|
||||
return of_register_platform_driver(&fire_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(fire_init);
|
||||
|
|
|
@ -91,7 +91,7 @@ struct pci_pbm_info {
|
|||
char *name;
|
||||
|
||||
/* OBP specific information. */
|
||||
struct of_device *op;
|
||||
struct platform_device *op;
|
||||
u64 ino_bitmap;
|
||||
|
||||
/* PBM I/O and Memory space resources. */
|
||||
|
|
|
@ -285,7 +285,7 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id)
|
|||
#define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */
|
||||
static void psycho_register_error_handlers(struct pci_pbm_info *pbm)
|
||||
{
|
||||
struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node);
|
||||
struct platform_device *op = of_find_device_by_node(pbm->op->dev.of_node);
|
||||
unsigned long base = pbm->controller_regs;
|
||||
u64 tmp;
|
||||
int err;
|
||||
|
@ -302,23 +302,23 @@ static void psycho_register_error_handlers(struct pci_pbm_info *pbm)
|
|||
* 5: POWER MANAGEMENT
|
||||
*/
|
||||
|
||||
if (op->num_irqs < 6)
|
||||
if (op->archdata.num_irqs < 6)
|
||||
return;
|
||||
|
||||
/* We really mean to ignore the return result here. Two
|
||||
* PCI controller share the same interrupt numbers and
|
||||
* drive the same front-end hardware.
|
||||
*/
|
||||
err = request_irq(op->irqs[1], psycho_ue_intr, IRQF_SHARED,
|
||||
err = request_irq(op->archdata.irqs[1], psycho_ue_intr, IRQF_SHARED,
|
||||
"PSYCHO_UE", pbm);
|
||||
err = request_irq(op->irqs[2], psycho_ce_intr, IRQF_SHARED,
|
||||
err = request_irq(op->archdata.irqs[2], psycho_ce_intr, IRQF_SHARED,
|
||||
"PSYCHO_CE", pbm);
|
||||
|
||||
/* This one, however, ought not to fail. We can just warn
|
||||
* about it since the system can still operate properly even
|
||||
* if this fails.
|
||||
*/
|
||||
err = request_irq(op->irqs[0], psycho_pcierr_intr, IRQF_SHARED,
|
||||
err = request_irq(op->archdata.irqs[0], psycho_pcierr_intr, IRQF_SHARED,
|
||||
"PSYCHO_PCIERR", pbm);
|
||||
if (err)
|
||||
printk(KERN_WARNING "%s: Could not register PCIERR, "
|
||||
|
@ -483,7 +483,7 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm,
|
|||
#define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL
|
||||
|
||||
static void __devinit psycho_pbm_init(struct pci_pbm_info *pbm,
|
||||
struct of_device *op, int is_pbm_a)
|
||||
struct platform_device *op, int is_pbm_a)
|
||||
{
|
||||
psycho_pbm_init_common(pbm, op, "PSYCHO", PBM_CHIP_TYPE_PSYCHO);
|
||||
psycho_pbm_strbuf_init(pbm, is_pbm_a);
|
||||
|
@ -503,7 +503,7 @@ static struct pci_pbm_info * __devinit psycho_find_sibling(u32 upa_portid)
|
|||
|
||||
#define PSYCHO_CONFIGSPACE 0x001000000UL
|
||||
|
||||
static int __devinit psycho_probe(struct of_device *op,
|
||||
static int __devinit psycho_probe(struct platform_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
const struct linux_prom64_registers *pr_regs;
|
||||
|
@ -612,7 +612,7 @@ static struct of_platform_driver psycho_driver = {
|
|||
|
||||
static int __init psycho_init(void)
|
||||
{
|
||||
return of_register_driver(&psycho_driver, &of_bus_type);
|
||||
return of_register_platform_driver(&psycho_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(psycho_init);
|
||||
|
|
|
@ -311,7 +311,7 @@ static irqreturn_t sabre_ce_intr(int irq, void *dev_id)
|
|||
static void sabre_register_error_handlers(struct pci_pbm_info *pbm)
|
||||
{
|
||||
struct device_node *dp = pbm->op->dev.of_node;
|
||||
struct of_device *op;
|
||||
struct platform_device *op;
|
||||
unsigned long base = pbm->controller_regs;
|
||||
u64 tmp;
|
||||
int err;
|
||||
|
@ -329,7 +329,7 @@ static void sabre_register_error_handlers(struct pci_pbm_info *pbm)
|
|||
* 2: CE ERR
|
||||
* 3: POWER FAIL
|
||||
*/
|
||||
if (op->num_irqs < 4)
|
||||
if (op->archdata.num_irqs < 4)
|
||||
return;
|
||||
|
||||
/* We clear the error bits in the appropriate AFSR before
|
||||
|
@ -341,7 +341,7 @@ static void sabre_register_error_handlers(struct pci_pbm_info *pbm)
|
|||
SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE),
|
||||
base + SABRE_UE_AFSR);
|
||||
|
||||
err = request_irq(op->irqs[1], sabre_ue_intr, 0, "SABRE_UE", pbm);
|
||||
err = request_irq(op->archdata.irqs[1], sabre_ue_intr, 0, "SABRE_UE", pbm);
|
||||
if (err)
|
||||
printk(KERN_WARNING "%s: Couldn't register UE, err=%d.\n",
|
||||
pbm->name, err);
|
||||
|
@ -351,11 +351,11 @@ static void sabre_register_error_handlers(struct pci_pbm_info *pbm)
|
|||
base + SABRE_CE_AFSR);
|
||||
|
||||
|
||||
err = request_irq(op->irqs[2], sabre_ce_intr, 0, "SABRE_CE", pbm);
|
||||
err = request_irq(op->archdata.irqs[2], sabre_ce_intr, 0, "SABRE_CE", pbm);
|
||||
if (err)
|
||||
printk(KERN_WARNING "%s: Couldn't register CE, err=%d.\n",
|
||||
pbm->name, err);
|
||||
err = request_irq(op->irqs[0], psycho_pcierr_intr, 0,
|
||||
err = request_irq(op->archdata.irqs[0], psycho_pcierr_intr, 0,
|
||||
"SABRE_PCIERR", pbm);
|
||||
if (err)
|
||||
printk(KERN_WARNING "%s: Couldn't register PCIERR, err=%d.\n",
|
||||
|
@ -443,7 +443,7 @@ static void __devinit sabre_scan_bus(struct pci_pbm_info *pbm,
|
|||
}
|
||||
|
||||
static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm,
|
||||
struct of_device *op)
|
||||
struct platform_device *op)
|
||||
{
|
||||
psycho_pbm_init_common(pbm, op, "SABRE", PBM_CHIP_TYPE_SABRE);
|
||||
pbm->pci_afsr = pbm->controller_regs + SABRE_PIOAFSR;
|
||||
|
@ -452,7 +452,7 @@ static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm,
|
|||
sabre_scan_bus(pbm, &op->dev);
|
||||
}
|
||||
|
||||
static int __devinit sabre_probe(struct of_device *op,
|
||||
static int __devinit sabre_probe(struct platform_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
const struct linux_prom64_registers *pr_regs;
|
||||
|
@ -606,7 +606,7 @@ static struct of_platform_driver sabre_driver = {
|
|||
|
||||
static int __init sabre_init(void)
|
||||
{
|
||||
return of_register_driver(&sabre_driver, &of_bus_type);
|
||||
return of_register_platform_driver(&sabre_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(sabre_init);
|
||||
|
|
|
@ -844,7 +844,7 @@ static int pbm_routes_this_ino(struct pci_pbm_info *pbm, u32 ino)
|
|||
*/
|
||||
static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm)
|
||||
{
|
||||
struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node);
|
||||
struct platform_device *op = of_find_device_by_node(pbm->op->dev.of_node);
|
||||
u64 tmp, err_mask, err_no_mask;
|
||||
int err;
|
||||
|
||||
|
@ -857,14 +857,14 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm)
|
|||
*/
|
||||
|
||||
if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) {
|
||||
err = request_irq(op->irqs[1], schizo_ue_intr, 0,
|
||||
err = request_irq(op->archdata.irqs[1], schizo_ue_intr, 0,
|
||||
"TOMATILLO_UE", pbm);
|
||||
if (err)
|
||||
printk(KERN_WARNING "%s: Could not register UE, "
|
||||
"err=%d\n", pbm->name, err);
|
||||
}
|
||||
if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) {
|
||||
err = request_irq(op->irqs[2], schizo_ce_intr, 0,
|
||||
err = request_irq(op->archdata.irqs[2], schizo_ce_intr, 0,
|
||||
"TOMATILLO_CE", pbm);
|
||||
if (err)
|
||||
printk(KERN_WARNING "%s: Could not register CE, "
|
||||
|
@ -872,10 +872,10 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm)
|
|||
}
|
||||
err = 0;
|
||||
if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) {
|
||||
err = request_irq(op->irqs[0], schizo_pcierr_intr, 0,
|
||||
err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
|
||||
"TOMATILLO_PCIERR", pbm);
|
||||
} else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) {
|
||||
err = request_irq(op->irqs[0], schizo_pcierr_intr, 0,
|
||||
err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
|
||||
"TOMATILLO_PCIERR", pbm);
|
||||
}
|
||||
if (err)
|
||||
|
@ -883,7 +883,7 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm)
|
|||
"err=%d\n", pbm->name, err);
|
||||
|
||||
if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) {
|
||||
err = request_irq(op->irqs[3], schizo_safarierr_intr, 0,
|
||||
err = request_irq(op->archdata.irqs[3], schizo_safarierr_intr, 0,
|
||||
"TOMATILLO_SERR", pbm);
|
||||
if (err)
|
||||
printk(KERN_WARNING "%s: Could not register SERR, "
|
||||
|
@ -939,7 +939,7 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm)
|
|||
|
||||
static void schizo_register_error_handlers(struct pci_pbm_info *pbm)
|
||||
{
|
||||
struct of_device *op = of_find_device_by_node(pbm->op->dev.of_node);
|
||||
struct platform_device *op = of_find_device_by_node(pbm->op->dev.of_node);
|
||||
u64 tmp, err_mask, err_no_mask;
|
||||
int err;
|
||||
|
||||
|
@ -952,14 +952,14 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm)
|
|||
*/
|
||||
|
||||
if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) {
|
||||
err = request_irq(op->irqs[1], schizo_ue_intr, 0,
|
||||
err = request_irq(op->archdata.irqs[1], schizo_ue_intr, 0,
|
||||
"SCHIZO_UE", pbm);
|
||||
if (err)
|
||||
printk(KERN_WARNING "%s: Could not register UE, "
|
||||
"err=%d\n", pbm->name, err);
|
||||
}
|
||||
if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) {
|
||||
err = request_irq(op->irqs[2], schizo_ce_intr, 0,
|
||||
err = request_irq(op->archdata.irqs[2], schizo_ce_intr, 0,
|
||||
"SCHIZO_CE", pbm);
|
||||
if (err)
|
||||
printk(KERN_WARNING "%s: Could not register CE, "
|
||||
|
@ -967,10 +967,10 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm)
|
|||
}
|
||||
err = 0;
|
||||
if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) {
|
||||
err = request_irq(op->irqs[0], schizo_pcierr_intr, 0,
|
||||
err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
|
||||
"SCHIZO_PCIERR", pbm);
|
||||
} else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) {
|
||||
err = request_irq(op->irqs[0], schizo_pcierr_intr, 0,
|
||||
err = request_irq(op->archdata.irqs[0], schizo_pcierr_intr, 0,
|
||||
"SCHIZO_PCIERR", pbm);
|
||||
}
|
||||
if (err)
|
||||
|
@ -978,7 +978,7 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm)
|
|||
"err=%d\n", pbm->name, err);
|
||||
|
||||
if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) {
|
||||
err = request_irq(op->irqs[3], schizo_safarierr_intr, 0,
|
||||
err = request_irq(op->archdata.irqs[3], schizo_safarierr_intr, 0,
|
||||
"SCHIZO_SERR", pbm);
|
||||
if (err)
|
||||
printk(KERN_WARNING "%s: Could not register SERR, "
|
||||
|
@ -1307,7 +1307,7 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
|
|||
}
|
||||
|
||||
static int __devinit schizo_pbm_init(struct pci_pbm_info *pbm,
|
||||
struct of_device *op, u32 portid,
|
||||
struct platform_device *op, u32 portid,
|
||||
int chip_type)
|
||||
{
|
||||
const struct linux_prom64_registers *regs;
|
||||
|
@ -1413,7 +1413,7 @@ static struct pci_pbm_info * __devinit schizo_find_sibling(u32 portid,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type)
|
||||
static int __devinit __schizo_init(struct platform_device *op, unsigned long chip_type)
|
||||
{
|
||||
struct device_node *dp = op->dev.of_node;
|
||||
struct pci_pbm_info *pbm;
|
||||
|
@ -1460,7 +1460,7 @@ out_err:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int __devinit schizo_probe(struct of_device *op,
|
||||
static int __devinit schizo_probe(struct platform_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
return __schizo_init(op, (unsigned long) match->data);
|
||||
|
@ -1501,7 +1501,7 @@ static struct of_platform_driver schizo_driver = {
|
|||
|
||||
static int __init schizo_init(void)
|
||||
{
|
||||
return of_register_driver(&schizo_driver, &of_bus_type);
|
||||
return of_register_platform_driver(&schizo_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(schizo_init);
|
||||
|
|
|
@ -879,7 +879,7 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
|
|||
#endif /* !(CONFIG_PCI_MSI) */
|
||||
|
||||
static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm,
|
||||
struct of_device *op, u32 devhandle)
|
||||
struct platform_device *op, u32 devhandle)
|
||||
{
|
||||
struct device_node *dp = op->dev.of_node;
|
||||
int err;
|
||||
|
@ -918,7 +918,7 @@ static int __devinit pci_sun4v_pbm_init(struct pci_pbm_info *pbm,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit pci_sun4v_probe(struct of_device *op,
|
||||
static int __devinit pci_sun4v_probe(struct platform_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
const struct linux_prom64_registers *regs;
|
||||
|
@ -1019,7 +1019,7 @@ static struct of_platform_driver pci_sun4v_driver = {
|
|||
|
||||
static int __init pci_sun4v_init(void)
|
||||
{
|
||||
return of_register_driver(&pci_sun4v_driver, &of_bus_type);
|
||||
return of_register_platform_driver(&pci_sun4v_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(pci_sun4v_init);
|
||||
|
|
|
@ -51,7 +51,7 @@ static void pmc_swift_idle(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int __devinit pmc_probe(struct of_device *op,
|
||||
static int __devinit pmc_probe(struct platform_device *op,
|
||||
const struct of_device_id *match)
|
||||
{
|
||||
regs = of_ioremap(&op->resource[0], 0,
|
||||
|
@ -89,7 +89,7 @@ static struct of_platform_driver pmc_driver = {
|
|||
|
||||
static int __init pmc_init(void)
|
||||
{
|
||||
return of_register_driver(&pmc_driver, &of_bus_type);
|
||||
return of_register_platform_driver(&pmc_driver);
|
||||
}
|
||||
|
||||
/* This driver is not critical to the boot process
|
||||
|
|
|
@ -33,10 +33,10 @@ static int __devinit has_button_interrupt(unsigned int irq, struct device_node *
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int __devinit power_probe(struct of_device *op, const struct of_device_id *match)
|
||||
static int __devinit power_probe(struct platform_device *op, const struct of_device_id *match)
|
||||
{
|
||||
struct resource *res = &op->resource[0];
|
||||
unsigned int irq= op->irqs[0];
|
||||
unsigned int irq = op->archdata.irqs[0];
|
||||
|
||||
power_reg = of_ioremap(res, 0, 0x4, "power");
|
||||
|
||||
|
@ -70,7 +70,7 @@ static struct of_platform_driver power_driver = {
|
|||
|
||||
static int __init power_init(void)
|
||||
{
|
||||
return of_register_driver(&power_driver, &of_platform_bus_type);
|
||||
return of_register_platform_driver(&power_driver);
|
||||
}
|
||||
|
||||
device_initcall(power_init);
|
||||
|
|
|
@ -9,14 +9,6 @@ extern void irq_trans_init(struct device_node *dp);
|
|||
|
||||
extern unsigned int prom_unique_id;
|
||||
|
||||
static inline int is_root_node(const struct device_node *dp)
|
||||
{
|
||||
if (!dp)
|
||||
return 0;
|
||||
|
||||
return (dp->parent == NULL);
|
||||
}
|
||||
|
||||
extern char *build_path_component(struct device_node *dp);
|
||||
extern void of_console_init(void);
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <asm/prom.h>
|
||||
#include <asm/oplib.h>
|
||||
|
@ -81,7 +81,7 @@ static void __init sun4v_path_component(struct device_node *dp, char *tmp_buf)
|
|||
return;
|
||||
|
||||
regs = rprop->value;
|
||||
if (!is_root_node(dp->parent)) {
|
||||
if (!of_node_is_root(dp->parent)) {
|
||||
sprintf(tmp_buf, "%s@%x,%x",
|
||||
dp->name,
|
||||
(unsigned int) (regs->phys_addr >> 32UL),
|
||||
|
@ -121,7 +121,7 @@ static void __init sun4u_path_component(struct device_node *dp, char *tmp_buf)
|
|||
return;
|
||||
|
||||
regs = prop->value;
|
||||
if (!is_root_node(dp->parent)) {
|
||||
if (!of_node_is_root(dp->parent)) {
|
||||
sprintf(tmp_buf, "%s@%x,%x",
|
||||
dp->name,
|
||||
(unsigned int) (regs->phys_addr >> 32UL),
|
||||
|
|
|
@ -244,7 +244,7 @@ char * __init build_full_name(struct device_node *dp)
|
|||
|
||||
n = prom_early_alloc(len);
|
||||
strcpy(n, dp->parent->full_name);
|
||||
if (!is_root_node(dp->parent)) {
|
||||
if (!of_node_is_root(dp->parent)) {
|
||||
strcpy(n + plen, "/");
|
||||
plen++;
|
||||
}
|
||||
|
|
|
@ -719,7 +719,7 @@ static unsigned int central_build_irq(struct device_node *dp,
|
|||
void *_data)
|
||||
{
|
||||
struct device_node *central_dp = _data;
|
||||
struct of_device *central_op = of_find_device_by_node(central_dp);
|
||||
struct platform_device *central_op = of_find_device_by_node(central_dp);
|
||||
struct resource *res;
|
||||
unsigned long imap, iclr;
|
||||
u32 tmp;
|
||||
|
|
|
@ -447,7 +447,7 @@ int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize,
|
|||
|
||||
}
|
||||
|
||||
void psycho_pbm_init_common(struct pci_pbm_info *pbm, struct of_device *op,
|
||||
void psycho_pbm_init_common(struct pci_pbm_info *pbm, struct platform_device *op,
|
||||
const char *chip_name, int chip_type)
|
||||
{
|
||||
struct device_node *dp = op->dev.of_node;
|
||||
|
|
|
@ -42,7 +42,7 @@ extern int psycho_iommu_init(struct pci_pbm_info *pbm, int tsbsize,
|
|||
unsigned long write_complete_offset);
|
||||
|
||||
extern void psycho_pbm_init_common(struct pci_pbm_info *pbm,
|
||||
struct of_device *op,
|
||||
struct platform_device *op,
|
||||
const char *chip_name, int chip_type);
|
||||
|
||||
#endif /* _PSYCHO_COMMON_H */
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
void sbus_set_sbus64(struct device *dev, int bursts)
|
||||
{
|
||||
struct iommu *iommu = dev->archdata.iommu;
|
||||
struct of_device *op = to_of_device(dev);
|
||||
struct platform_device *op = to_platform_device(dev);
|
||||
const struct linux_prom_registers *regs;
|
||||
unsigned long cfg_reg;
|
||||
int slot;
|
||||
|
@ -204,7 +204,7 @@ static unsigned long sysio_imap_to_iclr(unsigned long imap)
|
|||
return imap + diff;
|
||||
}
|
||||
|
||||
static unsigned int sbus_build_irq(struct of_device *op, unsigned int ino)
|
||||
static unsigned int sbus_build_irq(struct platform_device *op, unsigned int ino)
|
||||
{
|
||||
struct iommu *iommu = op->dev.archdata.iommu;
|
||||
unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
|
||||
|
@ -267,7 +267,7 @@ static unsigned int sbus_build_irq(struct of_device *op, unsigned int ino)
|
|||
#define SYSIO_UEAFSR_RESV2 0x0000001fffffffffUL /* Reserved */
|
||||
static irqreturn_t sysio_ue_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct of_device *op = dev_id;
|
||||
struct platform_device *op = dev_id;
|
||||
struct iommu *iommu = op->dev.archdata.iommu;
|
||||
unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
|
||||
unsigned long afsr_reg, afar_reg;
|
||||
|
@ -341,7 +341,7 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id)
|
|||
#define SYSIO_CEAFSR_RESV2 0x0000001fffffffffUL /* Reserved */
|
||||
static irqreturn_t sysio_ce_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct of_device *op = dev_id;
|
||||
struct platform_device *op = dev_id;
|
||||
struct iommu *iommu = op->dev.archdata.iommu;
|
||||
unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
|
||||
unsigned long afsr_reg, afar_reg;
|
||||
|
@ -420,7 +420,7 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id)
|
|||
#define SYSIO_SBAFSR_RESV3 0x0000001fffffffffUL /* Reserved */
|
||||
static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct of_device *op = dev_id;
|
||||
struct platform_device *op = dev_id;
|
||||
struct iommu *iommu = op->dev.archdata.iommu;
|
||||
unsigned long afsr_reg, afar_reg, reg_base;
|
||||
unsigned long afsr, afar, error_bits;
|
||||
|
@ -488,7 +488,7 @@ static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id)
|
|||
#define SYSIO_CE_INO 0x35
|
||||
#define SYSIO_SBUSERR_INO 0x36
|
||||
|
||||
static void __init sysio_register_error_handlers(struct of_device *op)
|
||||
static void __init sysio_register_error_handlers(struct platform_device *op)
|
||||
{
|
||||
struct iommu *iommu = op->dev.archdata.iommu;
|
||||
unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
|
||||
|
@ -534,7 +534,7 @@ static void __init sysio_register_error_handlers(struct of_device *op)
|
|||
}
|
||||
|
||||
/* Boot time initialization. */
|
||||
static void __init sbus_iommu_init(struct of_device *op)
|
||||
static void __init sbus_iommu_init(struct platform_device *op)
|
||||
{
|
||||
const struct linux_prom64_registers *pr;
|
||||
struct device_node *dp = op->dev.of_node;
|
||||
|
@ -663,7 +663,7 @@ static int __init sbus_init(void)
|
|||
struct device_node *dp;
|
||||
|
||||
for_each_node_by_name(dp, "sbus") {
|
||||
struct of_device *op = of_find_device_by_node(dp);
|
||||
struct platform_device *op = of_find_device_by_node(dp);
|
||||
|
||||
sbus_iommu_init(op);
|
||||
of_propagate_archdata(op);
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче