Commit 912b2539 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc

* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc:
  powerpc: add defconfig for Freescale MPC8349E-mITX board
  powerpc: Add base support for the Freescale MPC8349E-mITX eval board
  Documentation: correct values in MPC8548E SEC example node
  [POWERPC] Actually copy over i8259.c to arch/ppc/syslib this time
  [POWERPC] Add new interrupt mapping core and change platforms to use it
  [POWERPC] Copy i8259 code back to arch/ppc
  [POWERPC] New device-tree interrupt parsing code
  [POWERPC] Use the genirq framework
  [PATCH] genirq: Allow fasteoi handler to retrigger disabled interrupts
  [POWERPC] Update the SWIM3 (powermac) floppy driver
  [POWERPC] Fix error handling in detecting legacy serial ports
  [POWERPC] Fix booting on Momentum "Apache" board (a Maple derivative)
  [POWERPC] Fix various offb and BootX-related issues
  [POWERPC] Add a default config for 32-bit CHRP machines
  [POWERPC] fix implicit declaration on cell.
  [POWERPC] change get_property to return void *
parents 70b97a7f 39ab9c21
......@@ -1436,9 +1436,9 @@ platforms are moved over to use the flattened-device-tree model.
interrupts = <1d 3>;
interrupt-parent = <40000>;
num-channels = <4>;
channel-fifo-len = <24>;
channel-fifo-len = <18>;
exec-units-mask = <000000fe>;
descriptor-types-mask = <073f1127>;
descriptor-types-mask = <012b0ebf>;
};
......
This diff is collapsed.
This diff is collapsed.
......@@ -111,7 +111,7 @@ void __init btext_setup_display(int width, int height, int depth, int pitch,
logicalDisplayBase = (unsigned char *)address;
dispDeviceBase = (unsigned char *)address;
dispDeviceRowBytes = pitch;
dispDeviceDepth = depth;
dispDeviceDepth = depth == 15 ? 16 : depth;
dispDeviceRect[0] = dispDeviceRect[1] = 0;
dispDeviceRect[2] = width;
dispDeviceRect[3] = height;
......@@ -160,20 +160,28 @@ int btext_initialize(struct device_node *np)
unsigned long address = 0;
u32 *prop;
prop = (u32 *)get_property(np, "width", NULL);
prop = (u32 *)get_property(np, "linux,bootx-width", NULL);
if (prop == NULL)
prop = (u32 *)get_property(np, "width", NULL);
if (prop == NULL)
return -EINVAL;
width = *prop;
prop = (u32 *)get_property(np, "height", NULL);
prop = (u32 *)get_property(np, "linux,bootx-height", NULL);
if (prop == NULL)
prop = (u32 *)get_property(np, "height", NULL);
if (prop == NULL)
return -EINVAL;
height = *prop;
prop = (u32 *)get_property(np, "depth", NULL);
prop = (u32 *)get_property(np, "linux,bootx-depth", NULL);
if (prop == NULL)
prop = (u32 *)get_property(np, "depth", NULL);
if (prop == NULL)
return -EINVAL;
depth = *prop;
pitch = width * ((depth + 7) / 8);
prop = (u32 *)get_property(np, "linebytes", NULL);
prop = (u32 *)get_property(np, "linux,bootx-linebytes", NULL);
if (prop == NULL)
prop = (u32 *)get_property(np, "linebytes", NULL);
if (prop)
pitch = *prop;
if (pitch == 1)
......@@ -194,7 +202,7 @@ int btext_initialize(struct device_node *np)
g_max_loc_Y = height / 16;
dispDeviceBase = (unsigned char *)address;
dispDeviceRowBytes = pitch;
dispDeviceDepth = depth;
dispDeviceDepth = depth == 15 ? 16 : depth;
dispDeviceRect[0] = dispDeviceRect[1] = 0;
dispDeviceRect[2] = width;
dispDeviceRect[3] = height;
......
......@@ -323,13 +323,11 @@ int ibmebus_request_irq(struct ibmebus_dev *dev,
unsigned long irq_flags, const char * devname,
void *dev_id)
{
unsigned int irq = virt_irq_create_mapping(ist);
unsigned int irq = irq_create_mapping(NULL, ist, 0);
if (irq == NO_IRQ)
return -EINVAL;
irq = irq_offset_up(irq);
return request_irq(irq, handler,
irq_flags, devname, dev_id);
}
......@@ -337,12 +335,9 @@ EXPORT_SYMBOL(ibmebus_request_irq);
void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id)
{
unsigned int irq = virt_irq_create_mapping(ist);
unsigned int irq = irq_find_mapping(NULL, ist);
irq = irq_offset_up(irq);
free_irq(irq, dev_id);
return;
}
EXPORT_SYMBOL(ibmebus_free_irq);
......
This diff is collapsed.
......@@ -28,6 +28,7 @@ static struct legacy_serial_info {
struct device_node *np;
unsigned int speed;
unsigned int clock;
int irq_check_parent;
phys_addr_t taddr;
} legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS];
static unsigned int legacy_serial_count;
......@@ -36,7 +37,7 @@ static int legacy_serial_console = -1;
static int __init add_legacy_port(struct device_node *np, int want_index,
int iotype, phys_addr_t base,
phys_addr_t taddr, unsigned long irq,
upf_t flags)
upf_t flags, int irq_check_parent)
{
u32 *clk, *spd, clock = BASE_BAUD * 16;
int index;
......@@ -68,7 +69,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
if (legacy_serial_infos[index].np != 0) {
/* if we still have some room, move it, else override */
if (legacy_serial_count < MAX_LEGACY_SERIAL_PORTS) {
printk(KERN_INFO "Moved legacy port %d -> %d\n",
printk(KERN_DEBUG "Moved legacy port %d -> %d\n",
index, legacy_serial_count);
legacy_serial_ports[legacy_serial_count] =
legacy_serial_ports[index];
......@@ -76,7 +77,7 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
legacy_serial_infos[index];
legacy_serial_count++;
} else {
printk(KERN_INFO "Replacing legacy port %d\n", index);
printk(KERN_DEBUG "Replacing legacy port %d\n", index);
}
}
......@@ -95,10 +96,11 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
legacy_serial_infos[index].np = of_node_get(np);
legacy_serial_infos[index].clock = clock;
legacy_serial_infos[index].speed = spd ? *spd : 0;
legacy_serial_infos[index].irq_check_parent = irq_check_parent;
printk(KERN_INFO "Found legacy serial port %d for %s\n",
printk(KERN_DEBUG "Found legacy serial port %d for %s\n",
index, np->full_name);
printk(KERN_INFO " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n",
printk(KERN_DEBUG " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n",
(iotype == UPIO_PORT) ? "port" : "mem",
(unsigned long long)base, (unsigned long long)taddr, irq,
legacy_serial_ports[index].uartclk,
......@@ -126,11 +128,13 @@ static int __init add_legacy_soc_port(struct device_node *np,
return -1;
addr = of_translate_address(soc_dev, addrp);
if (addr == OF_BAD_ADDR)
return -1;
/* Add port, irq will be dealt with later. We passed a translated
* IO port value. It will be fixed up later along with the irq
*/
return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags);
return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags, 0);
}
static int __init add_legacy_isa_port(struct device_node *np,
......@@ -141,6 +145,8 @@ static int __init add_legacy_isa_port(struct device_node *np,
int index = -1;
phys_addr_t taddr;
DBG(" -> add_legacy_isa_port(%s)\n", np->full_name);
/* Get the ISA port number */
reg = (u32 *)get_property(np, "reg", NULL);
if (reg == NULL)
......@@ -161,9 +167,12 @@ static int __init add_legacy_isa_port(struct device_node *np,
/* Translate ISA address */
taddr = of_translate_address(np, reg);
if (taddr == OF_BAD_ADDR)
return -1;
/* Add port, irq will be dealt with later */
return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, NO_IRQ, UPF_BOOT_AUTOCONF);
return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr,
NO_IRQ, UPF_BOOT_AUTOCONF, 0);
}
......@@ -176,6 +185,8 @@ static int __init add_legacy_pci_port(struct device_node *np,
unsigned int flags;
int iotype, index = -1, lindex = 0;
DBG(" -> add_legacy_pci_port(%s)\n", np->full_name);
/* We only support ports that have a clock frequency properly
* encoded in the device-tree (that is have an fcode). Anything
* else can't be used that early and will be normally probed by
......@@ -194,6 +205,8 @@ static int __init add_legacy_pci_port(struct device_node *np,
/* We only support BAR 0 for now */
iotype = (flags & IORESOURCE_MEM) ? UPIO_MEM : UPIO_PORT;
addr = of_translate_address(pci_dev, addrp);
if (addr == OF_BAD_ADDR)
return -1;
/* Set the IO base to the same as the translated address for MMIO,
* or to the domain local IO base for PIO (it will be fixed up later)
......@@ -231,7 +244,8 @@ static int __init add_legacy_pci_port(struct device_node *np,
/* Add port, irq will be dealt with later. We passed a translated
* IO port value. It will be fixed up later along with the irq
*/
return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, UPF_BOOT_AUTOCONF);
return add_legacy_port(np, index, iotype, base, addr, NO_IRQ,
UPF_BOOT_AUTOCONF, np != pci_dev);
}
#endif
......@@ -362,27 +376,22 @@ static void __init fixup_port_irq(int index,
struct device_node *np,
struct plat_serial8250_port *port)
{
unsigned int virq;
DBG("fixup_port_irq(%d)\n", index);
/* Check for interrupts in that node */
if (np->n_intrs > 0) {
port->irq = np->intrs[0].line;
DBG(" port %d (%s), irq=%d\n",
index, np->full_name, port->irq);
return;
virq = irq_of_parse_and_map(np, 0);
if (virq == NO_IRQ && legacy_serial_infos[index].irq_check_parent) {
np = of_get_parent(np);
if (np == NULL)
return;
virq = irq_of_parse_and_map(np, 0);
of_node_put(np);
}
/* Check for interrupts in the parent */
np = of_get_parent(np);
if (np == NULL)
if (virq == NO_IRQ)
return;
if (np->n_intrs > 0) {
port->irq = np->intrs[0].line;
DBG(" port %d (%s), irq=%d\n",
index, np->full_name, port->irq);
}
of_node_put(np);
port->irq = virq;
}
static void __init fixup_port_pio(int index,
......
......@@ -51,12 +51,14 @@ _GLOBAL(call_do_softirq)
mtlr r0
blr
_GLOBAL(call___do_IRQ)
_GLOBAL(call_handle_irq)
ld r8,0(r7)
mflr r0
std r0,16(r1)
stdu r1,THREAD_SIZE-112(r5)
mr r1,r5
bl .__do_IRQ
mtctr r8
stdu r1,THREAD_SIZE-112(r6)
mr r1,r6
bctrl
ld r1,0(r1)
ld r0,16(r1)
mtlr r0
......
......@@ -1404,6 +1404,43 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
/* XXX FIXME - update OF device tree node interrupt property */
}
#ifdef CONFIG_PPC_MERGE
/* XXX This is a copy of the ppc64 version. This is temporary until we start
* merging the 2 PCI layers
*/
/*
* Reads the interrupt pin to determine if interrupt is use by card.
* If the interrupt is used, then gets the interrupt line from the
* openfirmware and sets it in the pci_dev and pci_config line.
*/
int pci_read_irq_line(struct pci_dev *pci_dev)
{
struct of_irq oirq;
unsigned int virq;
DBG("Try to map irq for %s...\n", pci_name(pci_dev));
if (of_irq_map_pci(pci_dev, &oirq)) {
DBG(" -> failed !\n");
return -1;
}
DBG(" -> got one, spec %d cells (0x%08x...) on %s\n",
oirq.size, oirq.specifier[0], oirq.controller->full_name);
virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size);
if(virq == NO_IRQ) {
DBG(" -> failed to map !\n");
return -1;
}
pci_dev->irq = virq;
pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq);
return 0;
}
EXPORT_SYMBOL(pci_read_irq_line);
#endif /* CONFIG_PPC_MERGE */
int pcibios_enable_device(struct pci_dev *dev, int mask)
{
u16 cmd, old_cmd;
......
......@@ -398,12 +398,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
} else {
dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
dev->rom_base_reg = PCI_ROM_ADDRESS;
/* Maybe do a default OF mapping here */
dev->irq = NO_IRQ;
if (node->n_intrs > 0) {
dev->irq = node->intrs[0].line;
pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
dev->irq);
}
}
pci_parse_of_addrs(node, dev);
......@@ -1288,23 +1284,26 @@ EXPORT_SYMBOL(pcibios_fixup_bus);
*/
int pci_read_irq_line(struct pci_dev *pci_dev)
{
u8 intpin;
struct device_node *node;
pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &intpin);
if (intpin == 0)
return 0;
struct of_irq oirq;
unsigned int virq;
node = pci_device_to_OF_node(pci_dev);
if (node == NULL)
return -1;
DBG("Try to map irq for %s...\n", pci_name(pci_dev));
if (node->n_intrs == 0)
if (of_irq_map_pci(pci_dev, &oirq)) {
DBG(" -> failed !\n");
return -1;
}
pci_dev->irq = node->intrs[0].line;
DBG(" -> got one, spec %d cells (0x%08x...) on %s\n",
oirq.size, oirq.specifier[0], oirq.controller->full_name);
pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, pci_dev->irq);
virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size);
if(virq == NO_IRQ) {
DBG(" -> failed to map !\n");
return -1;
}
pci_dev->irq = virq;
pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, virq);
return 0;
}
......
This diff is collapsed.
......@@ -1990,12 +1990,22 @@ static void __init flatten_device_tree(void)
static void __init fixup_device_tree_maple(void)
{
phandle isa;
u32 rloc = 0x01002000; /* IO space; PCI device = 4 */
u32 isa_ranges[6];
isa = call_prom("finddevice", 1, 1, ADDR("/ht@0/isa@4"));
char *name;
name = "/ht@0/isa@4";
isa = call_prom("finddevice", 1, 1, ADDR(name));
if (!PHANDLE_VALID(isa)) {
name = "/ht@0/isa@6";
isa = call_prom("finddevice", 1, 1, ADDR(name));
rloc = 0x01003000; /* IO space; PCI device = 6 */
}
if (!PHANDLE_VALID(isa))
return;
if (prom_getproplen(isa, "ranges") != 12)
return;
if (prom_getprop(isa, "ranges", isa_ranges, sizeof(isa_ranges))
== PROM_ERROR)
return;
......@@ -2005,15 +2015,15 @@ static void __init fixup_device_tree_maple(void)
isa_ranges[2] != 0x00010000)
return;
prom_printf("fixing up bogus ISA range on Maple...\n");
prom_printf("Fixing up bogus ISA range on Maple/Apache...\n");
isa_ranges[0] = 0x1;
isa_ranges[1] = 0x0;
isa_ranges[2] = 0x01002000; /* IO space; PCI device = 4 */
isa_ranges[2] = rloc;
isa_ranges[3] = 0x0;
isa_ranges[4] = 0x0;
isa_ranges[5] = 0x00010000;
prom_setprop(isa, "/ht@0/isa@4", "ranges",
prom_setprop(isa, name, "ranges",
isa_ranges, sizeof(isa_ranges));
}
#else
......
This diff is collapsed.
......@@ -297,19 +297,9 @@ unsigned long __init find_and_init_phbs(void)
struct device_node *node;
struct pci_controller *phb;
unsigned int index;
unsigned int root_size_cells = 0;
unsigned int *opprop = NULL;
struct device_node *root = of_find_node_by_path("/");
if (ppc64_interrupt_controller == IC_OPEN_PIC) {
opprop = (unsigned int *)get_property(root,
"platform-open-pic", NULL);
}
root_size_cells = prom_n_size_cells(root);
index = 0;
for (node = of_get_next_child(root, NULL);
node != NULL;
node = of_get_next_child(root, node)) {
......@@ -324,13 +314,6 @@ unsigned long __init find_and_init_phbs(void)
setup_phb(node, phb);
pci_process_bridge_OF_ranges(phb, node, 0);
pci_setup_phb_io(phb, index == 0);
#ifdef CONFIG_PPC_PSERIES
/* XXX This code need serious fixing ... --BenH */
if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
int addr = root_size_cells * (index + 2) - 1;
mpic_assign_isu(pSeries_mpic, index, opprop[addr]);
}
#endif
index++;
}
......
......@@ -51,7 +51,6 @@
extern void bootx_init(unsigned long r4, unsigned long phys);
boot_infos_t *boot_infos;
struct ide_machdep_calls ppc_ide_md;
int boot_cpuid;
......@@ -240,7 +239,6 @@ void __init setup_arch(char **cmdline_p)
ppc_md.init_early();
find_legacy_serial_ports();
finish_device_tree();
smp_setup_cpu_maps();
......
......@@ -361,12 +361,15 @@ void __init setup_system(void)
/*
* Fill the ppc64_caches & systemcfg structures with informations
* retrieved from the device-tree. Need to be called before
* finish_device_tree() since the later requires some of the
* informations filled up here to properly parse the interrupt tree.
* retrieved from the device-tree.
*/
initialize_cache_info();
/*
* Initialize irq remapping subsystem
*/
irq_early_init();
#ifdef CONFIG_PPC_RTAS
/*
* Initialize RTAS if available
......@@ -393,12 +396,6 @@ void __init setup_system(void)
*/
find_legacy_serial_ports();
/*
* "Finish" the device-tree, that is do the actual parsing of
* some of the properties like the interrupt map
*/
finish_device_tree();
/*
* Initialize xmon
*/
......@@ -427,8 +424,6 @@ void __init setup_system(void)
printk("-----------------------------------------------------\n");
printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size);
printk("ppc64_interrupt_controller = 0x%ld\n",
ppc64_interrupt_controller);
printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size());
printk("ppc64_caches.dcache_line_size = 0x%x\n",
ppc64_caches.dline_size);
......
......@@ -218,7 +218,6 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
{
struct vio_dev *viodev;
unsigned int *unit_address;
unsigned int *irq_p;
/* we need the 'device_type' property, in order to match with drivers */
if (of_node->type == NULL) {
......@@ -243,16 +242,7 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
viodev->dev.platform_data = of_node_get(of_node);
viodev->irq = NO_IRQ;
irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL);
if (irq_p) {
int virq = virt_irq_create_mapping(*irq_p);
if (virq == NO_IRQ) {
printk(KERN_ERR "Unable to allocate interrupt "
"number for %s\n", of_node->full_name);
} else
viodev->irq = irq_offset_up(virq);
}
viodev->irq = irq_of_parse_and_map(of_node, 0);
snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
viodev->name = of_node->name;
......
This diff is collapsed.
......@@ -4,3 +4,4 @@
obj-y := misc.o
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_MPC834x_SYS) += mpc834x_sys.o
obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment