diff options
Diffstat (limited to 'arch/powerpc/sysdev')
-rw-r--r-- | arch/powerpc/sysdev/fsl_rio.c | 18 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_soc.c | 6 | ||||
-rw-r--r-- | arch/powerpc/sysdev/ipic.c | 7 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mmio_nvram.c | 32 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 13 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/gpio.c | 4 | ||||
-rw-r--r-- | arch/powerpc/sysdev/qe_lib/qe_ic.c | 5 |
7 files changed, 70 insertions, 15 deletions
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index cbb3bed75d3..757a83fe5e5 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -1057,6 +1057,10 @@ int fsl_rio_setup(struct of_device *dev) law_start, law_size); ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL); + if (!ops) { + rc = -ENOMEM; + goto err_ops; + } ops->lcread = fsl_local_config_read; ops->lcwrite = fsl_local_config_write; ops->cread = fsl_rio_config_read; @@ -1064,6 +1068,10 @@ int fsl_rio_setup(struct of_device *dev) ops->dsend = fsl_rio_doorbell_send; port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL); + if (!port) { + rc = -ENOMEM; + goto err_port; + } port->id = 0; port->index = 0; @@ -1071,7 +1079,7 @@ int fsl_rio_setup(struct of_device *dev) if (!priv) { printk(KERN_ERR "Can't alloc memory for 'priv'\n"); rc = -ENOMEM; - goto err; + goto err_priv; } INIT_LIST_HEAD(&port->dbells); @@ -1169,11 +1177,13 @@ int fsl_rio_setup(struct of_device *dev) return 0; err: - if (priv) - iounmap(priv->regs_win); - kfree(ops); + iounmap(priv->regs_win); kfree(priv); +err_priv: kfree(port); +err_port: + kfree(ops); +err_ops: return rc; } diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 95dbc643c4f..adca4affcf1 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -37,6 +37,7 @@ #include <asm/irq.h> #include <asm/time.h> #include <asm/prom.h> +#include <asm/machdep.h> #include <sysdev/fsl_soc.h> #include <mm/mmu_decl.h> #include <asm/cpm2.h> @@ -383,8 +384,9 @@ static int __init setup_rstcr(void) if (!rstcr) printk (KERN_EMERG "Error: reset control register " "not mapped!\n"); - } else - printk (KERN_INFO "rstcr compatible register does not exist!\n"); + } else if (ppc_md.restart == fsl_rstcr_restart) + printk(KERN_ERR "No RSTCR register, warm reboot won't work\n"); + if (np) of_node_put(np); return 0; diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index 69e2630c906..cb7689c4bfb 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -735,8 +735,10 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) ipic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, NR_IPIC_INTS, &ipic_host_ops, 0); - if (ipic->irqhost == NULL) + if (ipic->irqhost == NULL) { + kfree(ipic); return NULL; + } ipic->regs = ioremap(res.start, res.end - res.start + 1); @@ -781,6 +783,9 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) primary_ipic = ipic; irq_set_default_host(primary_ipic->irqhost); + ipic_write(ipic->regs, IPIC_SIMSR_H, 0); + ipic_write(ipic->regs, IPIC_SIMSR_L, 0); + printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS, primary_ipic->regs); diff --git a/arch/powerpc/sysdev/mmio_nvram.c b/arch/powerpc/sysdev/mmio_nvram.c index 7b49633a4bd..20732420906 100644 --- a/arch/powerpc/sysdev/mmio_nvram.c +++ b/arch/powerpc/sysdev/mmio_nvram.c @@ -53,6 +53,23 @@ static ssize_t mmio_nvram_read(char *buf, size_t count, loff_t *index) return count; } +static unsigned char mmio_nvram_read_val(int addr) +{ + unsigned long flags; + unsigned char val; + + if (addr >= mmio_nvram_len) + return 0xff; + + spin_lock_irqsave(&mmio_nvram_lock, flags); + + val = ioread8(mmio_nvram_start + addr); + + spin_unlock_irqrestore(&mmio_nvram_lock, flags); + + return val; +} + static ssize_t mmio_nvram_write(char *buf, size_t count, loff_t *index) { unsigned long flags; @@ -72,6 +89,19 @@ static ssize_t mmio_nvram_write(char *buf, size_t count, loff_t *index) return count; } +void mmio_nvram_write_val(int addr, unsigned char val) +{ + unsigned long flags; + + if (addr < mmio_nvram_len) { + spin_lock_irqsave(&mmio_nvram_lock, flags); + + iowrite8(val, mmio_nvram_start + addr); + + spin_unlock_irqrestore(&mmio_nvram_lock, flags); + } +} + static ssize_t mmio_nvram_get_size(void) { return mmio_nvram_len; @@ -114,6 +144,8 @@ int __init mmio_nvram_init(void) printk(KERN_INFO "mmio NVRAM, %luk at 0x%lx mapped to %p\n", mmio_nvram_len >> 10, nvram_addr, mmio_nvram_start); + ppc_md.nvram_read_val = mmio_nvram_read_val; + ppc_md.nvram_write_val = mmio_nvram_write_val; ppc_md.nvram_read = mmio_nvram_read; ppc_md.nvram_write = mmio_nvram_write; ppc_md.nvram_size = mmio_nvram_get_size; diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 3981ae4cb58..30c44e6b041 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -230,14 +230,16 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigne { unsigned int isu = src_no >> mpic->isu_shift; unsigned int idx = src_no & mpic->isu_mask; + unsigned int val; + val = _mpic_read(mpic->reg_type, &mpic->isus[isu], + reg + (idx * MPIC_INFO(IRQ_STRIDE))); #ifdef CONFIG_MPIC_BROKEN_REGREAD if (reg == 0) - return mpic->isu_reg0_shadow[idx]; - else + val = (val & (MPIC_VECPRI_MASK | MPIC_VECPRI_ACTIVITY)) | + mpic->isu_reg0_shadow[src_no]; #endif - return _mpic_read(mpic->reg_type, &mpic->isus[isu], - reg + (idx * MPIC_INFO(IRQ_STRIDE))); + return val; } static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, @@ -251,7 +253,8 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, #ifdef CONFIG_MPIC_BROKEN_REGREAD if (reg == 0) - mpic->isu_reg0_shadow[idx] = value; + mpic->isu_reg0_shadow[src_no] = + value & ~(MPIC_VECPRI_MASK | MPIC_VECPRI_ACTIVITY); #endif } diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c index 3485288dce3..8e7a7767dd5 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/arch/powerpc/sysdev/qe_lib/gpio.c @@ -105,14 +105,14 @@ static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc); unsigned long flags; + qe_gpio_set(gc, gpio, val); + spin_lock_irqsave(&qe_gc->lock, flags); __par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_OUT, 0, 0, 0); spin_unlock_irqrestore(&qe_gc->lock, flags); - qe_gpio_set(gc, gpio, val); - return 0; } diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c index 074905c3ee5..3faa42e03a8 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c @@ -339,8 +339,10 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, qe_ic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, NR_QE_IC_INTS, &qe_ic_host_ops, 0); - if (qe_ic->irqhost == NULL) + if (qe_ic->irqhost == NULL) { + kfree(qe_ic); return; + } qe_ic->regs = ioremap(res.start, res.end - res.start + 1); @@ -352,6 +354,7 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags, if (qe_ic->virq_low == NO_IRQ) { printk(KERN_ERR "Failed to map QE_IC low IRQ\n"); + kfree(qe_ic); return; } |