ppc64: updates for BPA platform
Subsystems (4)
Arnd Bergmann
maintainercover ppc64: updates for BPA platform
These are a few updates for the BPA platform of ppc64. Only the first two patches are meant for inclusion, the others are provided here for people who are running on Cell already and cannot wait for clean versions of the patches ;-)
I also have lots of updates pending for spufs, but will send them separately.
Arnd <><
Arnd Bergmann
maintainerPATCH 1/4 ppc64: fix IPI on bpa_iic
This fixes a severe bug in the bpa_iic driver that caused all sorts of problems.
We had been using incorrect priority values for inter processor interrupts, which resulted in always doing CALL_FUNCTION instead of RESCHEDULE or DEBUGGER_BREAK.
The symptoms cured by this patch include bad performance on SMP systems spurious kernel panics in the IPI code.
arch/ppc64/kernel/bpa_iic.c +21 -7
@@ -205,6 +205,18 @@ static struct iic_regs __iomem *find_iic }#ifdef CONFIG_SMP + +/* Use the highest interrupt priorities for IPI */ +static inline int iic_ipi_to_irq (int ipi) +{ +return IIC_IPI_OFFSET +IIC_NUM_IPIS -1 - ipi; +} + +static inline int iic_irq_to_ipi (int irq) +{ +return IIC_NUM_IPIS -1 - (irq -IIC_IPI_OFFSET ); +} +void iic_setup_cpu (void ) {out_be64 (&__get_cpu_var (iic).regs->prio,0xff );
@@ -212,18 +224,20 @@ void iic_setup_cpu(void)void iic_cause_IPI (int cpu,int mesg) { -out_be64 (&per_cpu (iic, cpu).regs->generate, mesg); +out_be64 (&per_cpu (iic, cpu).regs->generate, (IIC_NUM_IPIS -1 - mesg) <<4 ); }static irqreturn_t iic_ipi_action (int irq,void *dev_id,struct pt_regs *regs) { - -smp_message_recv (irq -IIC_IPI_OFFSET , regs); +smp_message_recv (iic_irq_to_ipi (irq), regs);return IRQ_HANDLED ; } -static void iic_request_ipi (int irq,const char *name) +static void iic_request_ipi (int ipi,const char *name) { +int irq; + + irq =iic_ipi_to_irq (ipi);/* IPIs are marked SA_INTERRUPT as they must run with irqs * disabled */ get_irq_desc (irq)->handler = &iic_pic;
@@ -233,10 +247,10 @@ static void iic_request_ipi(int irq, convoid iic_request_IPIs (void ) { -iic_request_ipi (IIC_IPI_OFFSET +PPC_MSG_CALL_FUNCTION ,"IPI-call" ); -iic_request_ipi (IIC_IPI_OFFSET +PPC_MSG_RESCHEDULE ,"IPI-resched" ); +iic_request_ipi (PPC_MSG_CALL_FUNCTION ,"IPI-call" ); +iic_request_ipi (PPC_MSG_RESCHEDULE ,"IPI-resched" );#ifdef CONFIG_DEBUGGER -iic_request_ipi (IIC_IPI_OFFSET +PPC_MSG_DEBUGGER_BREAK ,"IPI-debug" ); +iic_request_ipi (PPC_MSG_DEBUGGER_BREAK ,"IPI-debug" );#endif /* CONFIG_DEBUGGER */ }#endif /* CONFIG_SMP */
Arnd Bergmann
maintainerPATCH 2/4 net: update the spider_net driver
In reply to Arnd BergmannThis update fixes a few bugs in the spider_net driver, relative to the version in 2.6.13-rc6-mm1. Please merge the updated driver in the 2.6.14 cycle.
- Prevent PCI posting problems by using synchronous register access in critical places
- Check return value from firmware device tree functions
- fix device cleanup
From: Jens Osterkamp <[email protected]>
drivers/net/spider_net.c +41 -11
@@ -109,6 +109,23 @@ }/** +* spider_net_write_reg_sync - writes to an SMMIO register of a card +* @card: device structure +* @reg: register to write to +* @value: value to write into the specified SMMIO register +* +* Unlike spider_net_write_reg, this will also make sure the +* data arrives on the card by reading the reg again. +*/ +static void +spider_net_write_reg_sync (struct spider_net_card *card,u32 reg,u32 value) +{ + value =cpu_to_le32 (value); +writel (value, card->regs + reg); + (void )readl (card->regs + reg); +} + +/** * spider_net_rx_irq_off - switch off rx irq on this spider card * @card: device structure *
@@ -123,7 +140,7 @@spin_lock_irqsave (&card->intmask_lock, flags); regvalue =spider_net_read_reg (card,SPIDER_NET_GHIINT0MSK ); regvalue &= ~SPIDER_NET_RXINT ; -spider_net_write_reg (card,SPIDER_NET_GHIINT0MSK , regvalue); +spider_net_write_reg_sync (card,SPIDER_NET_GHIINT0MSK , regvalue);spin_unlock_irqrestore (&card->intmask_lock, flags); }
@@ -196,7 +213,7 @@spin_lock_irqsave (&card->intmask_lock, flags); regvalue =spider_net_read_reg (card,SPIDER_NET_GHIINT0MSK ); regvalue |=SPIDER_NET_RXINT ; -spider_net_write_reg (card,SPIDER_NET_GHIINT0MSK , regvalue); +spider_net_write_reg_sync (card,SPIDER_NET_GHIINT0MSK , regvalue);spin_unlock_irqrestore (&card->intmask_lock, flags); }
@@ -215,7 +232,7 @@spin_lock_irqsave (&card->intmask_lock, flags); regvalue =spider_net_read_reg (card,SPIDER_NET_GHIINT0MSK ); regvalue &= ~SPIDER_NET_TXINT ; -spider_net_write_reg (card,SPIDER_NET_GHIINT0MSK , regvalue); +spider_net_write_reg_sync (card,SPIDER_NET_GHIINT0MSK , regvalue);spin_unlock_irqrestore (&card->intmask_lock, flags); }
@@ -234,7 +251,7 @@spin_lock_irqsave (&card->intmask_lock, flags); regvalue =spider_net_read_reg (card,SPIDER_NET_GHIINT0MSK ); regvalue |=SPIDER_NET_TXINT ; -spider_net_write_reg (card,SPIDER_NET_GHIINT0MSK , regvalue); +spider_net_write_reg_sync (card,SPIDER_NET_GHIINT0MSK , regvalue);spin_unlock_irqrestore (&card->intmask_lock, flags); }
@@ -813,6 +830,9 @@spider_net_write_reg (card,SPIDER_NET_GHIINT1MSK ,0 );spider_net_write_reg (card,SPIDER_NET_GHIINT2MSK ,0 ); +/* free_irq(netdev->irq, netdev);*/ +free_irq (to_pci_dev (netdev->class_dev.dev)->irq, netdev); +spider_net_write_reg (card,SPIDER_NET_GDTDMACCNTR ,SPIDER_NET_DMA_TX_FEND_VALUE );
@@ -822,10 +842,6 @@/* release chains */ spider_net_release_tx_chain (card,1 ); -/* switch off card */ -spider_net_write_reg (card,SPIDER_NET_CKRCTRL , -SPIDER_NET_CKRCTRL_STOP_VALUE ); -spider_net_free_chain (card, &card->tx_chain);spider_net_free_chain (card, &card->rx_chain);
@@ -1744,6 +1760,10 @@ goto register_int_failed;spider_net_enable_card (card); + +netif_start_queue (netdev); +netif_carrier_on (netdev); +netif_poll_enable (netdev);return 0 ;
@@ -2045,7 +2065,12 @@ netdev->irq = card->pdev->irq; dn =pci_device_to_OF_node (card->pdev); +if (!dn) +return -EIO ; + mac = (u8 *)get_property (dn,"local-mac-address" ,NULL ); +if (!mac) +return -EIO ;memcpy (addr.sa_data, mac,ETH_ALEN ); result =spider_net_set_mac (netdev, &addr);
@@ -2241,12 +2266,17 @@wait_event (card->waitq,atomic_read (&card->tx_timeout_task_counter) ==0 ); - +unregister_netdev (netdev); + +/* switch off card */ +spider_net_write_reg (card,SPIDER_NET_CKRCTRL , +SPIDER_NET_CKRCTRL_STOP_VALUE ); +spider_net_write_reg (card,SPIDER_NET_CKRCTRL , +SPIDER_NET_CKRCTRL_RUN_VALUE ); +spider_net_undo_pci_setup (card);free_netdev (netdev); - -free_irq (to_pci_dev (netdev->class_dev.dev)->irq, netdev); }static struct pci_driver spider_net_driver = {
Arnd Bergmann
maintainerPATCH 3/4 ppc64: add RTAS console driver
In reply to Arnd BergmannThe RTAS console driver can be used by all machines that abstract the system console through the {get,put}-term-char interface. It replaces the hvconsole on BPA, because we don't run under a hypervisor.
This driver needs to be redone as a special case of hvconsole, so there is no point in applying the patch to generic kernels. You will however need it if you intend to run on present Cell hardware.
From: Utz Bacher <[email protected]>
drivers/char/Kconfig +6 -0
@@ -560,6 +560,12 @@ config HVC_CONSOLE console. This driver allows each pSeries partition to have a console which is accessed via the HMC. +config RTASCONS + bool "RTAS firmware console support" + depends on PPC_RTAS + help + RTAS console support. + config HVCS tristate "IBM Hypervisor Virtual Console Server support" depends on PPC_PSERIES
drivers/char/Makefile +1 -0
@@ -40,6 +40,7 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o obj-$(CONFIG_SX) += sx.o generic_serial.o obj-$(CONFIG_RIO) += rio/ generic_serial.o +obj-$(CONFIG_RTASCONS) += rtascons.o obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvc_vio.o hvsi.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
drivers/char/rtascons.c +339 -0
339 lines not on this page · raw message
Re: [PATCH 3/4] ppc64: add RTAS console driver
Quoted 12 lines · Arnd Bergmann
The RTAS console driver can be used by all machines that abstract the system console through the {get,put}-term-char interface. It replaces the hvconsole on BPA, because we don't run under a hypervisor.
This driver needs to be redone as a special case of hvconsole, so there is no point in applying the patch to generic kernels. You will however need it if you intend to run on present Cell hardware.
From: Utz Bacher <[email protected]>
Signed-off-by Arnd Bergmann <[email protected]>
<snip>
Quoted 2 lines
drivers/char/rtascons.c 2005-08-18 17:31:21.912892064 renamed from drivers/char/rtascons.c 1969-12-31 19:00:00.000000000 -0500 +0
-0
<snip>
Quoted 1 line
+#define
RTASCONS_TIMEOUT((HZ + 99) / 100)
msecs_to_jiffies(10)? Or perhaps leave it in milliseconds with a comment as such (see below)?
<snip>
Quoted 8 lines
drivers/char/rtascons.c 2005-08-18 17:31:21.912892064 renamed from drivers/char/rtascons.c 1969-12-31 19:00:00.000000000 -0500 +8
-0+static int +krtasconsd(void *unused) +{ + daemonize("krtasconsd"); + + for (;;) { + if (cpus_empty(cpus_in_xmon)) { + rtascons_poll();
drivers/char/rtascons.c 2005-08-18 17:31:21.912892064
Quoted 10 lines
drivers/char/rtascons.c 2005-08-18 17:31:21.912892064 renamed from drivers/char/rtascons.c 1969-12-31 19:00:00.000000000 -0500 +10
-0+ /* no need for atomic access */ + if (rtascons_buffer_used) { + spin_lock(&rtascons_buffer_lock); + rtascons_flush_chars(); + spin_unlock(&rtascons_buffer_lock); + } + } + + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(RTASCONS_TIMEOUT);
Couldn't this be msleep_interruptible(RTASCONS_TIMEOUT) [if you make RTASCONS_TIMEOUT in milliseconds]?
Thanks,
Nish
Arnd Bergmann
maintainerPATCH 4/4 ppc64: small hacks for running on BPA hardware
In reply to Arnd BergmannThis patch is not meant for inclusion in a generic kernel, but is currently needed to support the available HW. Most of the things done in here are workarounds for deficiencies in the present hardware or firmware that will be solved there in later releases.
arch/ppc64/Kconfig +6 -0
@@ -221,6 +221,12 @@ config SMP If you don't know what to do here, say Y. +config BE_DD2 + bool "BE DD2.x Errata Workaround Support" + depends on PPC_BPA + ---help--- + This support enables BE DD2.x errata workarounds. + config NR_CPUS int "Maximum number of CPUs (2-128)" range 2 128
arch/ppc64/kernel/Makefile +1 -1
@@ -33,7 +33,7 @@ obj-$(CONFIG_PPC_PSERIES) += pSeries_pci pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \ pSeries_setup.o pSeries_iommu.o -obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \ +obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o bpa_pci.o \ bpa_iic.o spider-pic.o obj-$(CONFIG_KEXEC) += machine_kexec.o
arch/ppc64/kernel/bpa_iommu.c +12 -3
@@ -245,8 +245,6 @@ set_iocmd_config(void __iomem *base) }/* FIXME: get these from the device tree */ -#define ioc_base 0x20000511000ull -#define ioc_mmio_base 0x20000510000ull#define ioid 0x48a#define iopt_phys_offset (- 0x20000000)/* We have a 512MB offset from the SB */ #define io_page_size 0x1000000
@@ -278,12 +276,22 @@ static void bpa_map_iommu(void)void __iomem *base;ioste ioste;unsigned long index; - +struct device_node *node; +unsigned long *handle, ioc_mmio_base, ioc_base; +int nodelen; + +for (node =of_find_node_by_type (NULL ,"cpu" ); + node; + node =of_find_node_by_type (node,"cpu" )) { + handle = (unsigned long *)get_property (node,"ioc-translation" , &nodelen); + ioc_base = *handle +0x1000 ; + base =__ioremap (ioc_base,0x1000 , _PAGE_NO_CACHE);pr_debug ("%lx mapped to %p\n" , ioc_base, base);set_iocmd_config (base);iounmap (base); + ioc_mmio_base = *handle; base =__ioremap (ioc_mmio_base,0x1000 , _PAGE_NO_CACHE);pr_debug ("%lx mapped to %p\n" , ioc_mmio_base, base);
@@ -302,6 +310,7 @@ static void bpa_map_iommu(void) map_iopt_entry(address)); }iounmap (base); + } }
arch/ppc64/kernel/bpa_pci.c +83 -0
83 lines not on this page · raw message
arch/ppc64/kernel/bpa_setup.c +3 -0
@@ -54,6 +54,8 @@ #define DBG(fmt...)#endif +extern void bpa_final_fixup (void ); +void bpa_get_cpuinfo (struct seq_file *m) {struct device_node *root;
@@ -129,6 +131,7 @@ struct machdep_calls __initdata bpa_md = .setup_arch = bpa_setup_arch, .init_early = bpa_init_early, .get_cpuinfo = bpa_get_cpuinfo, + .pcibios_fixup = bpa_final_fixup, .restart = rtas_restart, .power_off = rtas_power_off, .halt = rtas_halt,
arch/ppc64/kernel/head.S +42 -2
66 lines not on this page · raw message
arch/ppc64/kernel/prom_init.c +2 -0
@@ -1365,6 +1365,8 @@ static int __init prom_find_machine_typereturn PLATFORM_POWERMAC ;if (strstr (p,RELOC ("Momentum,Maple" )))return PLATFORM_MAPLE ; +if (strstr (p,RELOC ("IBM,CPB" ))) +return PLATFORM_BPA ; i += sl +1 ; } }
arch/ppc64/kernel/spider-pic.c +9 -2
@@ -84,10 +84,11 @@ static void __iomem *spider_get_irq_confstatic void spider_enable_irq (unsigned int irq) { +int nodeid = (irq /IIC_NODE_STRIDE ) *0x10 ;void __iomem *cfg =spider_get_irq_config (irq); irq =spider_get_nr (irq); -out_be32 (cfg,in_be32 (cfg) |0x3107000eu ); +out_be32 (cfg,in_be32 (cfg) |0x3107000eu | nodeid);out_be32 (cfg +4 ,in_be32 (cfg +4 ) |0x00020000u | irq); }
@@ -150,13 +151,17 @@ int spider_get_irq(unsigned long int_penvoid spider_init_IRQ (void ) {int node; +#if 0 struct device_node *dn;unsigned int *property; +#endif long spiderpic; +long pics[] = {0x24000008000 ,0x34000008000 };int n;/* FIXME: detect multiple PICs as soon as the device tree has them */ -for (node =0 ; node <1 ; node++) { +for (node =0 ; node <=1 ; node++) { +#if 0 dn =of_find_node_by_path ("/" ); n =prom_n_addr_cells (dn); property = (unsigned int *) get_property(dn,
@@ -166,6 +171,8 @@ void spider_init_IRQ(void)continue ;for (spiderpic =0 ; n >0 ; --n) spiderpic = (spiderpic <<32 ) + *property++; +#endif + spiderpic = pics[node];printk (KERN_DEBUG "SPIDER addr: %lx\n" , spiderpic); spider_pics[node] =__ioremap (spiderpic,0x800 , _PAGE_NO_CACHE);for (n =0 ; n <IIC_NUM_EXT ; n++) {
include/asm-ppc64/processor.h +1 -1
@@ -438,7 +438,7 @@ struct thread_struct { .fs = KERNEL_DS, \ .fpr = {0}, \ .fpscr = 0, \ - .fpexc_mode = MSR_FE0|MSR_FE1, \ + .fpexc_mode = 0, \ }/*
include/linux/pci_ids.h +2 -0
@@ -1611,6 +1611,8 @@#define PCI_DEVICE_ID_TOSHIBA_TX4927 0x0180#define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108#define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3 +#define PCI_DEVICE_ID_TOSHIBA_SPIDER_OHCI 0x01b6 +#define PCI_DEVICE_ID_TOSHIBA_SPIDER_EHCI 0x01b5#define PCI_VENDOR_ID_RICOH 0x1180#define PCI_DEVICE_ID_RICOH_RL5C465 0x0465