diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/boot/pm.c | 6 | ||||
-rw-r--r-- | arch/powerpc/kernel/ibmebus.c | 30 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spu_base.c | 24 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/platform.h | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/repository.c | 29 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/spu.c | 2 |
6 files changed, 61 insertions, 31 deletions
diff --git a/arch/i386/boot/pm.c b/arch/i386/boot/pm.c index 6be9ca811d1..09fb342cc62 100644 --- a/arch/i386/boot/pm.c +++ b/arch/i386/boot/pm.c @@ -122,7 +122,11 @@ static void setup_gdt(void) /* DS: data, read/write, 4 GB, base 0 */ [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff), }; - struct gdt_ptr gdt; + /* Xen HVM incorrectly stores a pointer to the gdt_ptr, instead + of the gdt_ptr contents. Thus, make it static so it will + stay in memory, at least long enough that we switch to the + proper kernel GDT. */ + static struct gdt_ptr gdt; gdt.len = sizeof(boot_gdt)-1; gdt.ptr = (u32)&boot_gdt + (ds() << 4); diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 9a8c9af43b2..d6a38cd5018 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -188,33 +188,21 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_node( struct device_node *dn) { struct ibmebus_dev *dev; - const char *loc_code; - int length; - - loc_code = of_get_property(dn, "ibm,loc-code", NULL); - if (!loc_code) { - printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n", - __FUNCTION__, dn->name ? dn->name : "<unknown>"); - return ERR_PTR(-EINVAL); - } - - if (strlen(loc_code) == 0) { - printk(KERN_WARNING "%s: 'ibm,loc-code' is invalid\n", - __FUNCTION__); - return ERR_PTR(-EINVAL); - } + int i, len, bus_len; dev = kzalloc(sizeof(struct ibmebus_dev), GFP_KERNEL); - if (!dev) { + if (!dev) return ERR_PTR(-ENOMEM); - } dev->ofdev.node = of_node_get(dn); - length = strlen(loc_code); - memcpy(dev->ofdev.dev.bus_id, loc_code - + (length - min(length, BUS_ID_SIZE - 1)), - min(length, BUS_ID_SIZE - 1)); + len = strlen(dn->full_name + 1); + bus_len = min(len, BUS_ID_SIZE - 1); + memcpy(dev->ofdev.dev.bus_id, dn->full_name + 1 + + (len - bus_len), bus_len); + for (i = 0; i < bus_len; i++) + if (dev->ofdev.dev.bus_id[i] == '/') + dev->ofdev.dev.bus_id[i] = '_'; /* Register with generic device framework. */ if (ibmebus_register_device_common(dev, dn->name) != 0) { diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 095a30304c5..106d2921e2d 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -236,27 +236,34 @@ static irqreturn_t spu_irq_class_0(int irq, void *data) { struct spu *spu; + unsigned long stat, mask; spu = data; - spu->class_0_pending = 1; + + mask = spu_int_mask_get(spu, 0); + stat = spu_int_stat_get(spu, 0); + stat &= mask; + + spin_lock(&spu->register_lock); + spu->class_0_pending |= stat; + spin_unlock(&spu->register_lock); + spu->stop_callback(spu); + spu_int_stat_clear(spu, 0, stat); + return IRQ_HANDLED; } int spu_irq_class_0_bottom(struct spu *spu) { - unsigned long stat, mask; unsigned long flags; - - spu->class_0_pending = 0; + unsigned long stat; spin_lock_irqsave(&spu->register_lock, flags); - mask = spu_int_mask_get(spu, 0); - stat = spu_int_stat_get(spu, 0); - - stat &= mask; + stat = spu->class_0_pending; + spu->class_0_pending = 0; if (stat & 1) /* invalid DMA alignment */ __spu_trap_dma_align(spu); @@ -267,7 +274,6 @@ spu_irq_class_0_bottom(struct spu *spu) if (stat & 4) /* error on SPU */ __spu_trap_error(spu); - spu_int_stat_clear(spu, 0, stat); spin_unlock_irqrestore(&spu->register_lock, flags); return (stat & 0x7) ? -EIO : 0; diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h index 87d52060fec..2eb8f92704b 100644 --- a/arch/powerpc/platforms/ps3/platform.h +++ b/arch/powerpc/platforms/ps3/platform.h @@ -83,6 +83,7 @@ enum ps3_dev_type { PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */ PS3_DEV_TYPE_SB_GPIO = 6, PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */ + PS3_DEV_TYPE_STOR_DUMMY = 32, PS3_DEV_TYPE_NOACCESS = 255, }; diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index 8cc37cfea0f..1c94824f7b6 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c @@ -349,6 +349,35 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) return result; } + if (tmp.bus_type == PS3_BUS_TYPE_STORAGE) { + /* + * A storage device may show up in the repository before the + * hypervisor has finished probing its type and regions + */ + unsigned int num_regions; + + if (tmp.dev_type == PS3_DEV_TYPE_STOR_DUMMY) { + pr_debug("%s:%u storage device not ready\n", __func__, + __LINE__); + return -ENODEV; + } + + result = ps3_repository_read_stor_dev_num_regions(tmp.bus_index, + tmp.dev_index, + &num_regions); + if (result) { + pr_debug("%s:%d read_stor_dev_num_regions failed\n", + __func__, __LINE__); + return result; + } + + if (!num_regions) { + pr_debug("%s:%u storage device has no regions yet\n", + __func__, __LINE__); + return -ENODEV; + } + } + result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index, &tmp.dev_id); diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c index ac2a4b8a4c1..d1630a074ac 100644 --- a/arch/powerpc/platforms/ps3/spu.c +++ b/arch/powerpc/platforms/ps3/spu.c @@ -505,6 +505,8 @@ static void mfc_sr1_set(struct spu *spu, u64 sr1) static const u64 allowed = ~(MFC_STATE1_LOCAL_STORAGE_DECODE_MASK | MFC_STATE1_PROBLEM_STATE_MASK); + sr1 |= MFC_STATE1_MASTER_RUN_CONTROL_MASK; + BUG_ON((sr1 & allowed) != (spu_pdata(spu)->cache.sr1 & allowed)); spu_pdata(spu)->cache.sr1 = sr1; |