diff options
Diffstat (limited to 'arch/powerpc/sysdev')
28 files changed, 967 insertions, 156 deletions
diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 88f4ae787832..402d2212162f 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c | |||
| @@ -185,7 +185,7 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) | |||
| 185 | axon_ram_bank_id++; | 185 | axon_ram_bank_id++; |
| 186 | 186 | ||
| 187 | dev_info(&device->dev, "Found memory controller on %s\n", | 187 | dev_info(&device->dev, "Found memory controller on %s\n", |
| 188 | device->node->full_name); | 188 | device->dev.of_node->full_name); |
| 189 | 189 | ||
| 190 | bank = kzalloc(sizeof(struct axon_ram_bank), GFP_KERNEL); | 190 | bank = kzalloc(sizeof(struct axon_ram_bank), GFP_KERNEL); |
| 191 | if (bank == NULL) { | 191 | if (bank == NULL) { |
| @@ -198,7 +198,7 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) | |||
| 198 | 198 | ||
| 199 | bank->device = device; | 199 | bank->device = device; |
| 200 | 200 | ||
| 201 | if (of_address_to_resource(device->node, 0, &resource) != 0) { | 201 | if (of_address_to_resource(device->dev.of_node, 0, &resource) != 0) { |
| 202 | dev_err(&device->dev, "Cannot access device tree\n"); | 202 | dev_err(&device->dev, "Cannot access device tree\n"); |
| 203 | rc = -EFAULT; | 203 | rc = -EFAULT; |
| 204 | goto failed; | 204 | goto failed; |
| @@ -253,7 +253,7 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id) | |||
| 253 | blk_queue_logical_block_size(bank->disk->queue, AXON_RAM_SECTOR_SIZE); | 253 | blk_queue_logical_block_size(bank->disk->queue, AXON_RAM_SECTOR_SIZE); |
| 254 | add_disk(bank->disk); | 254 | add_disk(bank->disk); |
| 255 | 255 | ||
| 256 | bank->irq_id = irq_of_parse_and_map(device->node, 0); | 256 | bank->irq_id = irq_of_parse_and_map(device->dev.of_node, 0); |
| 257 | if (bank->irq_id == NO_IRQ) { | 257 | if (bank->irq_id == NO_IRQ) { |
| 258 | dev_err(&device->dev, "Cannot access ECC interrupt ID\n"); | 258 | dev_err(&device->dev, "Cannot access ECC interrupt ID\n"); |
| 259 | rc = -EFAULT; | 259 | rc = -EFAULT; |
| @@ -327,12 +327,12 @@ static struct of_device_id axon_ram_device_id[] = { | |||
| 327 | }; | 327 | }; |
| 328 | 328 | ||
| 329 | static struct of_platform_driver axon_ram_driver = { | 329 | static struct of_platform_driver axon_ram_driver = { |
| 330 | .match_table = axon_ram_device_id, | ||
| 331 | .probe = axon_ram_probe, | 330 | .probe = axon_ram_probe, |
| 332 | .remove = axon_ram_remove, | 331 | .remove = axon_ram_remove, |
| 333 | .driver = { | 332 | .driver = { |
| 334 | .owner = THIS_MODULE, | 333 | .name = AXON_RAM_MODULE_NAME, |
| 335 | .name = AXON_RAM_MODULE_NAME, | 334 | .owner = THIS_MODULE, |
| 335 | .of_match_table = axon_ram_device_id, | ||
| 336 | }, | 336 | }, |
| 337 | }; | 337 | }; |
| 338 | 338 | ||
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c index 378ebd9aac18..a7c5c470af14 100644 --- a/arch/powerpc/sysdev/bestcomm/bestcomm.c +++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c | |||
| @@ -377,7 +377,7 @@ mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match) | |||
| 377 | printk(KERN_INFO "DMA: MPC52xx BestComm driver\n"); | 377 | printk(KERN_INFO "DMA: MPC52xx BestComm driver\n"); |
| 378 | 378 | ||
| 379 | /* Get the bestcomm node */ | 379 | /* Get the bestcomm node */ |
| 380 | of_node_get(op->node); | 380 | of_node_get(op->dev.of_node); |
| 381 | 381 | ||
| 382 | /* Prepare SRAM */ | 382 | /* Prepare SRAM */ |
| 383 | ofn_sram = of_find_matching_node(NULL, mpc52xx_sram_ids); | 383 | ofn_sram = of_find_matching_node(NULL, mpc52xx_sram_ids); |
| @@ -406,10 +406,10 @@ mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match) | |||
| 406 | } | 406 | } |
| 407 | 407 | ||
| 408 | /* Save the node */ | 408 | /* Save the node */ |
| 409 | bcom_eng->ofnode = op->node; | 409 | bcom_eng->ofnode = op->dev.of_node; |
| 410 | 410 | ||
| 411 | /* Get, reserve & map io */ | 411 | /* Get, reserve & map io */ |
| 412 | if (of_address_to_resource(op->node, 0, &res_bcom)) { | 412 | if (of_address_to_resource(op->dev.of_node, 0, &res_bcom)) { |
| 413 | printk(KERN_ERR DRIVER_NAME ": " | 413 | printk(KERN_ERR DRIVER_NAME ": " |
| 414 | "Can't get resource\n"); | 414 | "Can't get resource\n"); |
| 415 | rv = -EINVAL; | 415 | rv = -EINVAL; |
| @@ -453,7 +453,7 @@ error_sramclean: | |||
| 453 | kfree(bcom_eng); | 453 | kfree(bcom_eng); |
| 454 | bcom_sram_cleanup(); | 454 | bcom_sram_cleanup(); |
| 455 | error_ofput: | 455 | error_ofput: |
| 456 | of_node_put(op->node); | 456 | of_node_put(op->dev.of_node); |
| 457 | 457 | ||
| 458 | printk(KERN_ERR "DMA: MPC52xx BestComm init failed !\n"); | 458 | printk(KERN_ERR "DMA: MPC52xx BestComm init failed !\n"); |
| 459 | 459 | ||
| @@ -494,14 +494,12 @@ MODULE_DEVICE_TABLE(of, mpc52xx_bcom_of_match); | |||
| 494 | 494 | ||
| 495 | 495 | ||
| 496 | static struct of_platform_driver mpc52xx_bcom_of_platform_driver = { | 496 | static struct of_platform_driver mpc52xx_bcom_of_platform_driver = { |
| 497 | .owner = THIS_MODULE, | ||
| 498 | .name = DRIVER_NAME, | ||
| 499 | .match_table = mpc52xx_bcom_of_match, | ||
| 500 | .probe = mpc52xx_bcom_probe, | 497 | .probe = mpc52xx_bcom_probe, |
| 501 | .remove = mpc52xx_bcom_remove, | 498 | .remove = mpc52xx_bcom_remove, |
| 502 | .driver = { | 499 | .driver = { |
| 503 | .name = DRIVER_NAME, | 500 | .name = DRIVER_NAME, |
| 504 | .owner = THIS_MODULE, | 501 | .owner = THIS_MODULE, |
| 502 | .of_match_table = mpc52xx_bcom_of_match, | ||
| 505 | }, | 503 | }, |
| 506 | }; | 504 | }; |
| 507 | 505 | ||
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index ecad10d4e928..8d103ca6d6ab 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/irq.h> | 31 | #include <linux/irq.h> |
| 32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
| 33 | #include <linux/spinlock.h> | 33 | #include <linux/spinlock.h> |
| 34 | #include <linux/slab.h> | ||
| 34 | #include <asm/page.h> | 35 | #include <asm/page.h> |
| 35 | #include <asm/pgtable.h> | 36 | #include <asm/pgtable.h> |
| 36 | #include <asm/8xx_immap.h> | 37 | #include <asm/8xx_immap.h> |
| @@ -485,9 +486,6 @@ int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode) | |||
| 485 | return -EINVAL; | 486 | return -EINVAL; |
| 486 | } | 487 | } |
| 487 | 488 | ||
| 488 | if (reg == &mpc8xx_immr->im_cpm.cp_sicr && mode == CPM_CLK_RX) | ||
| 489 | shift += 3; | ||
| 490 | |||
| 491 | for (i = 0; i < ARRAY_SIZE(clk_map); i++) { | 489 | for (i = 0; i < ARRAY_SIZE(clk_map); i++) { |
| 492 | if (clk_map[i][0] == target && clk_map[i][1] == clock) { | 490 | if (clk_map[i][0] == target && clk_map[i][1] == clock) { |
| 493 | bits = clk_map[i][2]; | 491 | bits = clk_map[i][2]; |
| @@ -502,6 +500,17 @@ int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode) | |||
| 502 | 500 | ||
| 503 | bits <<= shift; | 501 | bits <<= shift; |
| 504 | mask <<= shift; | 502 | mask <<= shift; |
| 503 | |||
| 504 | if (reg == &mpc8xx_immr->im_cpm.cp_sicr) { | ||
| 505 | if (mode == CPM_CLK_RTX) { | ||
| 506 | bits |= bits << 3; | ||
| 507 | mask |= mask << 3; | ||
| 508 | } else if (mode == CPM_CLK_RX) { | ||
| 509 | bits <<= 3; | ||
| 510 | mask <<= 3; | ||
| 511 | } | ||
| 512 | } | ||
| 513 | |||
| 505 | out_be32(reg, (in_be32(reg) & ~mask) | bits); | 514 | out_be32(reg, (in_be32(reg) & ~mask) | bits); |
| 506 | 515 | ||
| 507 | return 0; | 516 | return 0; |
diff --git a/arch/powerpc/sysdev/cpm2.c b/arch/powerpc/sysdev/cpm2.c index eb5927212fab..8dc1e24f3c23 100644 --- a/arch/powerpc/sysdev/cpm2.c +++ b/arch/powerpc/sysdev/cpm2.c | |||
| @@ -244,9 +244,6 @@ int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode) | |||
| 244 | return -EINVAL; | 244 | return -EINVAL; |
| 245 | } | 245 | } |
| 246 | 246 | ||
| 247 | if (mode == CPM_CLK_RX) | ||
| 248 | shift += 3; | ||
| 249 | |||
| 250 | for (i = 0; i < ARRAY_SIZE(clk_map); i++) { | 247 | for (i = 0; i < ARRAY_SIZE(clk_map); i++) { |
| 251 | if (clk_map[i][0] == target && clk_map[i][1] == clock) { | 248 | if (clk_map[i][0] == target && clk_map[i][1] == clock) { |
| 252 | bits = clk_map[i][2]; | 249 | bits = clk_map[i][2]; |
| @@ -259,6 +256,14 @@ int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode) | |||
| 259 | bits <<= shift; | 256 | bits <<= shift; |
| 260 | mask <<= shift; | 257 | mask <<= shift; |
| 261 | 258 | ||
| 259 | if (mode == CPM_CLK_RTX) { | ||
| 260 | bits |= bits << 3; | ||
| 261 | mask |= mask << 3; | ||
| 262 | } else if (mode == CPM_CLK_RX) { | ||
| 263 | bits <<= 3; | ||
| 264 | mask <<= 3; | ||
| 265 | } | ||
| 266 | |||
| 262 | out_be32(reg, (in_be32(reg) & ~mask) | bits); | 267 | out_be32(reg, (in_be32(reg) & ~mask) | bits); |
| 263 | 268 | ||
| 264 | cpm2_unmap(im_cpmux); | 269 | cpm2_unmap(im_cpmux); |
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c index 9de72c96e6d1..88b9812c854f 100644 --- a/arch/powerpc/sysdev/cpm_common.c +++ b/arch/powerpc/sysdev/cpm_common.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
| 22 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
| 23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
| 24 | #include <linux/slab.h> | ||
| 24 | 25 | ||
| 25 | #include <asm/udbg.h> | 26 | #include <asm/udbg.h> |
| 26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index bafc3f85360d..559db2b846a9 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | 29 | ||
| 30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
| 31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
| 32 | #include <linux/slab.h> | ||
| 33 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
| 34 | #include <linux/spinlock.h> | 33 | #include <linux/spinlock.h> |
| 35 | #include <linux/string.h> | 34 | #include <linux/string.h> |
| @@ -37,7 +36,8 @@ | |||
| 37 | #include <linux/dma-mapping.h> | 36 | #include <linux/dma-mapping.h> |
| 38 | #include <linux/vmalloc.h> | 37 | #include <linux/vmalloc.h> |
| 39 | #include <linux/suspend.h> | 38 | #include <linux/suspend.h> |
| 40 | #include <linux/lmb.h> | 39 | #include <linux/memblock.h> |
| 40 | #include <linux/gfp.h> | ||
| 41 | #include <asm/io.h> | 41 | #include <asm/io.h> |
| 42 | #include <asm/prom.h> | 42 | #include <asm/prom.h> |
| 43 | #include <asm/iommu.h> | 43 | #include <asm/iommu.h> |
| @@ -232,7 +232,7 @@ static int __init dart_init(struct device_node *dart_node) | |||
| 232 | * that to work around what looks like a problem with the HT bridge | 232 | * that to work around what looks like a problem with the HT bridge |
| 233 | * prefetching into invalid pages and corrupting data | 233 | * prefetching into invalid pages and corrupting data |
| 234 | */ | 234 | */ |
| 235 | tmp = lmb_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE); | 235 | tmp = memblock_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE); |
| 236 | dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) & | 236 | dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) & |
| 237 | DARTMAP_RPNMASK); | 237 | DARTMAP_RPNMASK); |
| 238 | 238 | ||
| @@ -407,7 +407,7 @@ void __init alloc_dart_table(void) | |||
| 407 | if (iommu_is_off) | 407 | if (iommu_is_off) |
| 408 | return; | 408 | return; |
| 409 | 409 | ||
| 410 | if (!iommu_force_on && lmb_end_of_DRAM() <= 0x40000000ull) | 410 | if (!iommu_force_on && memblock_end_of_DRAM() <= 0x40000000ull) |
| 411 | return; | 411 | return; |
| 412 | 412 | ||
| 413 | /* 512 pages (2MB) is max DART tablesize. */ | 413 | /* 512 pages (2MB) is max DART tablesize. */ |
| @@ -416,7 +416,7 @@ void __init alloc_dart_table(void) | |||
| 416 | * will blow up an entire large page anyway in the kernel mapping | 416 | * will blow up an entire large page anyway in the kernel mapping |
| 417 | */ | 417 | */ |
| 418 | dart_tablebase = (unsigned long) | 418 | dart_tablebase = (unsigned long) |
| 419 | abs_to_virt(lmb_alloc_base(1UL<<24, 1UL<<24, 0x80000000L)); | 419 | abs_to_virt(memblock_alloc_base(1UL<<24, 1UL<<24, 0x80000000L)); |
| 420 | 420 | ||
| 421 | printk(KERN_INFO "DART table allocated at: %lx\n", dart_tablebase); | 421 | printk(KERN_INFO "DART table allocated at: %lx\n", dart_tablebase); |
| 422 | } | 422 | } |
diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c index 714ec02fed2e..eca4545dd52e 100644 --- a/arch/powerpc/sysdev/fsl_gtm.c +++ b/arch/powerpc/sysdev/fsl_gtm.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
| 21 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
| 22 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
| 23 | #include <linux/slab.h> | ||
| 23 | #include <asm/fsl_gtm.h> | 24 | #include <asm/fsl_gtm.h> |
| 24 | 25 | ||
| 25 | #define GTCFR_STP(x) ((x) & 1 ? 1 << 5 : 1 << 1) | 26 | #define GTCFR_STP(x) ((x) & 1 ? 1 << 5 : 1 << 1) |
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index e094367d7739..962c2d8dd8d9 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2007-2008 Freescale Semiconductor, Inc. All rights reserved. | 2 | * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. |
| 3 | * | 3 | * |
| 4 | * Author: Tony Li <tony.li@freescale.com> | 4 | * Author: Tony Li <tony.li@freescale.com> |
| 5 | * Jason Jin <Jason.jin@freescale.com> | 5 | * Jason Jin <Jason.jin@freescale.com> |
| @@ -16,19 +16,26 @@ | |||
| 16 | #include <linux/bootmem.h> | 16 | #include <linux/bootmem.h> |
| 17 | #include <linux/msi.h> | 17 | #include <linux/msi.h> |
| 18 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
| 19 | #include <linux/slab.h> | ||
| 19 | #include <linux/of_platform.h> | 20 | #include <linux/of_platform.h> |
| 20 | #include <sysdev/fsl_soc.h> | 21 | #include <sysdev/fsl_soc.h> |
| 21 | #include <asm/prom.h> | 22 | #include <asm/prom.h> |
| 22 | #include <asm/hw_irq.h> | 23 | #include <asm/hw_irq.h> |
| 23 | #include <asm/ppc-pci.h> | 24 | #include <asm/ppc-pci.h> |
| 25 | #include <asm/mpic.h> | ||
| 24 | #include "fsl_msi.h" | 26 | #include "fsl_msi.h" |
| 25 | 27 | ||
| 28 | LIST_HEAD(msi_head); | ||
| 29 | |||
| 26 | struct fsl_msi_feature { | 30 | struct fsl_msi_feature { |
| 27 | u32 fsl_pic_ip; | 31 | u32 fsl_pic_ip; |
| 28 | u32 msiir_offset; | 32 | u32 msiir_offset; |
| 29 | }; | 33 | }; |
| 30 | 34 | ||
| 31 | static struct fsl_msi *fsl_msi; | 35 | struct fsl_msi_cascade_data { |
| 36 | struct fsl_msi *msi_data; | ||
| 37 | int index; | ||
| 38 | }; | ||
| 32 | 39 | ||
| 33 | static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg) | 40 | static inline u32 fsl_msi_read(u32 __iomem *base, unsigned int reg) |
| 34 | { | 41 | { |
| @@ -53,10 +60,12 @@ static struct irq_chip fsl_msi_chip = { | |||
| 53 | static int fsl_msi_host_map(struct irq_host *h, unsigned int virq, | 60 | static int fsl_msi_host_map(struct irq_host *h, unsigned int virq, |
| 54 | irq_hw_number_t hw) | 61 | irq_hw_number_t hw) |
| 55 | { | 62 | { |
| 63 | struct fsl_msi *msi_data = h->host_data; | ||
| 56 | struct irq_chip *chip = &fsl_msi_chip; | 64 | struct irq_chip *chip = &fsl_msi_chip; |
| 57 | 65 | ||
| 58 | irq_to_desc(virq)->status |= IRQ_TYPE_EDGE_FALLING; | 66 | irq_to_desc(virq)->status |= IRQ_TYPE_EDGE_FALLING; |
| 59 | 67 | ||
| 68 | set_irq_chip_data(virq, msi_data); | ||
| 60 | set_irq_chip_and_handler(virq, chip, handle_edge_irq); | 69 | set_irq_chip_and_handler(virq, chip, handle_edge_irq); |
| 61 | 70 | ||
| 62 | return 0; | 71 | return 0; |
| @@ -95,11 +104,12 @@ static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type) | |||
| 95 | static void fsl_teardown_msi_irqs(struct pci_dev *pdev) | 104 | static void fsl_teardown_msi_irqs(struct pci_dev *pdev) |
| 96 | { | 105 | { |
| 97 | struct msi_desc *entry; | 106 | struct msi_desc *entry; |
| 98 | struct fsl_msi *msi_data = fsl_msi; | 107 | struct fsl_msi *msi_data; |
| 99 | 108 | ||
| 100 | list_for_each_entry(entry, &pdev->msi_list, list) { | 109 | list_for_each_entry(entry, &pdev->msi_list, list) { |
| 101 | if (entry->irq == NO_IRQ) | 110 | if (entry->irq == NO_IRQ) |
| 102 | continue; | 111 | continue; |
| 112 | msi_data = get_irq_data(entry->irq); | ||
| 103 | set_irq_msi(entry->irq, NULL); | 113 | set_irq_msi(entry->irq, NULL); |
| 104 | msi_bitmap_free_hwirqs(&msi_data->bitmap, | 114 | msi_bitmap_free_hwirqs(&msi_data->bitmap, |
| 105 | virq_to_hw(entry->irq), 1); | 115 | virq_to_hw(entry->irq), 1); |
| @@ -110,9 +120,10 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev) | |||
| 110 | } | 120 | } |
| 111 | 121 | ||
| 112 | static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, | 122 | static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, |
| 113 | struct msi_msg *msg) | 123 | struct msi_msg *msg, |
| 124 | struct fsl_msi *fsl_msi_data) | ||
| 114 | { | 125 | { |
| 115 | struct fsl_msi *msi_data = fsl_msi; | 126 | struct fsl_msi *msi_data = fsl_msi_data; |
| 116 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); | 127 | struct pci_controller *hose = pci_bus_to_host(pdev->bus); |
| 117 | u32 base = 0; | 128 | u32 base = 0; |
| 118 | 129 | ||
| @@ -129,14 +140,19 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, | |||
| 129 | 140 | ||
| 130 | static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | 141 | static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) |
| 131 | { | 142 | { |
| 132 | int rc, hwirq; | 143 | int rc, hwirq = -ENOMEM; |
| 133 | unsigned int virq; | 144 | unsigned int virq; |
| 134 | struct msi_desc *entry; | 145 | struct msi_desc *entry; |
| 135 | struct msi_msg msg; | 146 | struct msi_msg msg; |
| 136 | struct fsl_msi *msi_data = fsl_msi; | 147 | struct fsl_msi *msi_data; |
| 137 | 148 | ||
| 138 | list_for_each_entry(entry, &pdev->msi_list, list) { | 149 | list_for_each_entry(entry, &pdev->msi_list, list) { |
| 139 | hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); | 150 | list_for_each_entry(msi_data, &msi_head, list) { |
| 151 | hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); | ||
| 152 | if (hwirq >= 0) | ||
| 153 | break; | ||
| 154 | } | ||
| 155 | |||
| 140 | if (hwirq < 0) { | 156 | if (hwirq < 0) { |
| 141 | rc = hwirq; | 157 | rc = hwirq; |
| 142 | pr_debug("%s: fail allocating msi interrupt\n", | 158 | pr_debug("%s: fail allocating msi interrupt\n", |
| @@ -153,25 +169,31 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
| 153 | rc = -ENOSPC; | 169 | rc = -ENOSPC; |
| 154 | goto out_free; | 170 | goto out_free; |
| 155 | } | 171 | } |
| 172 | set_irq_data(virq, msi_data); | ||
| 156 | set_irq_msi(virq, entry); | 173 | set_irq_msi(virq, entry); |
| 157 | 174 | ||
| 158 | fsl_compose_msi_msg(pdev, hwirq, &msg); | 175 | fsl_compose_msi_msg(pdev, hwirq, &msg, msi_data); |
| 159 | write_msi_msg(virq, &msg); | 176 | write_msi_msg(virq, &msg); |
| 160 | } | 177 | } |
| 161 | return 0; | 178 | return 0; |
| 162 | 179 | ||
| 163 | out_free: | 180 | out_free: |
| 181 | /* free by the caller of this function */ | ||
| 164 | return rc; | 182 | return rc; |
| 165 | } | 183 | } |
| 166 | 184 | ||
| 167 | static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) | 185 | static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) |
| 168 | { | 186 | { |
| 169 | unsigned int cascade_irq; | 187 | unsigned int cascade_irq; |
| 170 | struct fsl_msi *msi_data = fsl_msi; | 188 | struct fsl_msi *msi_data; |
| 171 | int msir_index = -1; | 189 | int msir_index = -1; |
| 172 | u32 msir_value = 0; | 190 | u32 msir_value = 0; |
| 173 | u32 intr_index; | 191 | u32 intr_index; |
| 174 | u32 have_shift = 0; | 192 | u32 have_shift = 0; |
| 193 | struct fsl_msi_cascade_data *cascade_data; | ||
| 194 | |||
| 195 | cascade_data = (struct fsl_msi_cascade_data *)get_irq_data(irq); | ||
| 196 | msi_data = cascade_data->msi_data; | ||
| 175 | 197 | ||
| 176 | raw_spin_lock(&desc->lock); | 198 | raw_spin_lock(&desc->lock); |
| 177 | if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) { | 199 | if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) { |
| @@ -186,13 +208,13 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc) | |||
| 186 | if (unlikely(desc->status & IRQ_INPROGRESS)) | 208 | if (unlikely(desc->status & IRQ_INPROGRESS)) |
| 187 | goto unlock; | 209 | goto unlock; |
| 188 | 210 | ||
| 189 | msir_index = (int)desc->handler_data; | 211 | msir_index = cascade_data->index; |
| 190 | 212 | ||
| 191 | if (msir_index >= NR_MSI_REG) | 213 | if (msir_index >= NR_MSI_REG) |
| 192 | cascade_irq = NO_IRQ; | 214 | cascade_irq = NO_IRQ; |
| 193 | 215 | ||
| 194 | desc->status |= IRQ_INPROGRESS; | 216 | desc->status |= IRQ_INPROGRESS; |
| 195 | switch (fsl_msi->feature & FSL_PIC_IP_MASK) { | 217 | switch (msi_data->feature & FSL_PIC_IP_MASK) { |
| 196 | case FSL_PIC_IP_MPIC: | 218 | case FSL_PIC_IP_MPIC: |
| 197 | msir_value = fsl_msi_read(msi_data->msi_regs, | 219 | msir_value = fsl_msi_read(msi_data->msi_regs, |
| 198 | msir_index * 0x10); | 220 | msir_index * 0x10); |
| @@ -228,6 +250,30 @@ unlock: | |||
| 228 | raw_spin_unlock(&desc->lock); | 250 | raw_spin_unlock(&desc->lock); |
| 229 | } | 251 | } |
| 230 | 252 | ||
| 253 | static int fsl_of_msi_remove(struct of_device *ofdev) | ||
| 254 | { | ||
| 255 | struct fsl_msi *msi = ofdev->dev.platform_data; | ||
| 256 | int virq, i; | ||
| 257 | struct fsl_msi_cascade_data *cascade_data; | ||
| 258 | |||
| 259 | if (msi->list.prev != NULL) | ||
| 260 | list_del(&msi->list); | ||
| 261 | for (i = 0; i < NR_MSI_REG; i++) { | ||
| 262 | virq = msi->msi_virqs[i]; | ||
| 263 | if (virq != NO_IRQ) { | ||
| 264 | cascade_data = get_irq_data(virq); | ||
| 265 | kfree(cascade_data); | ||
| 266 | irq_dispose_mapping(virq); | ||
| 267 | } | ||
| 268 | } | ||
| 269 | if (msi->bitmap.bitmap) | ||
| 270 | msi_bitmap_free(&msi->bitmap); | ||
| 271 | iounmap(msi->msi_regs); | ||
| 272 | kfree(msi); | ||
| 273 | |||
| 274 | return 0; | ||
| 275 | } | ||
| 276 | |||
| 231 | static int __devinit fsl_of_msi_probe(struct of_device *dev, | 277 | static int __devinit fsl_of_msi_probe(struct of_device *dev, |
| 232 | const struct of_device_id *match) | 278 | const struct of_device_id *match) |
| 233 | { | 279 | { |
| @@ -238,17 +284,20 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, | |||
| 238 | int virt_msir; | 284 | int virt_msir; |
| 239 | const u32 *p; | 285 | const u32 *p; |
| 240 | struct fsl_msi_feature *features = match->data; | 286 | struct fsl_msi_feature *features = match->data; |
| 287 | struct fsl_msi_cascade_data *cascade_data = NULL; | ||
| 288 | int len; | ||
| 289 | u32 offset; | ||
| 241 | 290 | ||
| 242 | printk(KERN_DEBUG "Setting up Freescale MSI support\n"); | 291 | printk(KERN_DEBUG "Setting up Freescale MSI support\n"); |
| 243 | 292 | ||
| 244 | msi = kzalloc(sizeof(struct fsl_msi), GFP_KERNEL); | 293 | msi = kzalloc(sizeof(struct fsl_msi), GFP_KERNEL); |
| 245 | if (!msi) { | 294 | if (!msi) { |
| 246 | dev_err(&dev->dev, "No memory for MSI structure\n"); | 295 | dev_err(&dev->dev, "No memory for MSI structure\n"); |
| 247 | err = -ENOMEM; | 296 | return -ENOMEM; |
| 248 | goto error_out; | ||
| 249 | } | 297 | } |
| 298 | dev->dev.platform_data = msi; | ||
| 250 | 299 | ||
| 251 | msi->irqhost = irq_alloc_host(dev->node, IRQ_HOST_MAP_LINEAR, | 300 | msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR, |
| 252 | NR_MSI_IRQS, &fsl_msi_host_ops, 0); | 301 | NR_MSI_IRQS, &fsl_msi_host_ops, 0); |
| 253 | 302 | ||
| 254 | if (msi->irqhost == NULL) { | 303 | if (msi->irqhost == NULL) { |
| @@ -258,10 +307,10 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, | |||
| 258 | } | 307 | } |
| 259 | 308 | ||
| 260 | /* Get the MSI reg base */ | 309 | /* Get the MSI reg base */ |
| 261 | err = of_address_to_resource(dev->node, 0, &res); | 310 | err = of_address_to_resource(dev->dev.of_node, 0, &res); |
| 262 | if (err) { | 311 | if (err) { |
| 263 | dev_err(&dev->dev, "%s resource error!\n", | 312 | dev_err(&dev->dev, "%s resource error!\n", |
| 264 | dev->node->full_name); | 313 | dev->dev.of_node->full_name); |
| 265 | goto error_out; | 314 | goto error_out; |
| 266 | } | 315 | } |
| 267 | 316 | ||
| @@ -284,40 +333,60 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev, | |||
| 284 | goto error_out; | 333 | goto error_out; |
| 285 | } | 334 | } |
| 286 | 335 | ||
| 287 | p = of_get_property(dev->node, "interrupts", &count); | 336 | p = of_get_property(dev->dev.of_node, "interrupts", &count); |
| 288 | if (!p) { | 337 | if (!p) { |
| 289 | dev_err(&dev->dev, "no interrupts property found on %s\n", | 338 | dev_err(&dev->dev, "no interrupts property found on %s\n", |
| 290 | dev->node->full_name); | 339 | dev->dev.of_node->full_name); |
| 291 | err = -ENODEV; | 340 | err = -ENODEV; |
| 292 | goto error_out; | 341 | goto error_out; |
| 293 | } | 342 | } |
| 294 | if (count % 8 != 0) { | 343 | if (count % 8 != 0) { |
| 295 | dev_err(&dev->dev, "Malformed interrupts property on %s\n", | 344 | dev_err(&dev->dev, "Malformed interrupts property on %s\n", |
| 296 | dev->node->full_name); | 345 | dev->dev.of_node->full_name); |
| 297 | err = -EINVAL; | 346 | err = -EINVAL; |
| 298 | goto error_out; | 347 | goto error_out; |
| 299 | } | 348 | } |
| 349 | offset = 0; | ||
| 350 | p = of_get_property(dev->dev.of_node, "msi-available-ranges", &len); | ||
| 351 | if (p) | ||
| 352 | offset = *p / IRQS_PER_MSI_REG; | ||
| 300 | 353 | ||
| 301 | count /= sizeof(u32); | 354 | count /= sizeof(u32); |
| 302 | for (i = 0; i < count / 2; i++) { | 355 | for (i = 0; i < min(count / 2, NR_MSI_REG); i++) { |
| 303 | if (i > NR_MSI_REG) | 356 | virt_msir = irq_of_parse_and_map(dev->dev.of_node, i); |
| 304 | break; | ||
| 305 | virt_msir = irq_of_parse_and_map(dev->node, i); | ||
| 306 | if (virt_msir != NO_IRQ) { | 357 | if (virt_msir != NO_IRQ) { |
| 307 | set_irq_data(virt_msir, (void *)i); | 358 | cascade_data = kzalloc( |
| 359 | sizeof(struct fsl_msi_cascade_data), | ||
| 360 | GFP_KERNEL); | ||
| 361 | if (!cascade_data) { | ||
| 362 | dev_err(&dev->dev, | ||
| 363 | "No memory for MSI cascade data\n"); | ||
| 364 | err = -ENOMEM; | ||
| 365 | goto error_out; | ||
| 366 | } | ||
| 367 | msi->msi_virqs[i] = virt_msir; | ||
| 368 | cascade_data->index = i + offset; | ||
| 369 | cascade_data->msi_data = msi; | ||
| 370 | set_irq_data(virt_msir, (void *)cascade_data); | ||
| 308 | set_irq_chained_handler(virt_msir, fsl_msi_cascade); | 371 | set_irq_chained_handler(virt_msir, fsl_msi_cascade); |
| 309 | } | 372 | } |
| 310 | } | 373 | } |
| 311 | 374 | ||
| 312 | fsl_msi = msi; | 375 | list_add_tail(&msi->list, &msi_head); |
| 313 | 376 | ||
| 314 | WARN_ON(ppc_md.setup_msi_irqs); | 377 | /* The multiple setting ppc_md.setup_msi_irqs will not harm things */ |
| 315 | ppc_md.setup_msi_irqs = fsl_setup_msi_irqs; | 378 | if (!ppc_md.setup_msi_irqs) { |
| 316 | ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs; | 379 | ppc_md.setup_msi_irqs = fsl_setup_msi_irqs; |
| 317 | ppc_md.msi_check_device = fsl_msi_check_device; | 380 | ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs; |
| 381 | ppc_md.msi_check_device = fsl_msi_check_device; | ||
| 382 | } else if (ppc_md.setup_msi_irqs != fsl_setup_msi_irqs) { | ||
| 383 | dev_err(&dev->dev, "Different MSI driver already installed!\n"); | ||
| 384 | err = -ENODEV; | ||
| 385 | goto error_out; | ||
| 386 | } | ||
| 318 | return 0; | 387 | return 0; |
| 319 | error_out: | 388 | error_out: |
| 320 | kfree(msi); | 389 | fsl_of_msi_remove(dev); |
| 321 | return err; | 390 | return err; |
| 322 | } | 391 | } |
| 323 | 392 | ||
| @@ -344,9 +413,13 @@ static const struct of_device_id fsl_of_msi_ids[] = { | |||
| 344 | }; | 413 | }; |
| 345 | 414 | ||
| 346 | static struct of_platform_driver fsl_of_msi_driver = { | 415 | static struct of_platform_driver fsl_of_msi_driver = { |
| 347 | .name = "fsl-msi", | 416 | .driver = { |
| 348 | .match_table = fsl_of_msi_ids, | 417 | .name = "fsl-msi", |
| 418 | .owner = THIS_MODULE, | ||
| 419 | .of_match_table = fsl_of_msi_ids, | ||
| 420 | }, | ||
| 349 | .probe = fsl_of_msi_probe, | 421 | .probe = fsl_of_msi_probe, |
| 422 | .remove = fsl_of_msi_remove, | ||
| 350 | }; | 423 | }; |
| 351 | 424 | ||
| 352 | static __init int fsl_of_msi_init(void) | 425 | static __init int fsl_of_msi_init(void) |
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h index 331c7e7025b7..624580c252d7 100644 --- a/arch/powerpc/sysdev/fsl_msi.h +++ b/arch/powerpc/sysdev/fsl_msi.h | |||
| @@ -32,8 +32,11 @@ struct fsl_msi { | |||
| 32 | u32 msi_addr_hi; | 32 | u32 msi_addr_hi; |
| 33 | void __iomem *msi_regs; | 33 | void __iomem *msi_regs; |
| 34 | u32 feature; | 34 | u32 feature; |
| 35 | int msi_virqs[NR_MSI_REG]; | ||
| 35 | 36 | ||
| 36 | struct msi_bitmap bitmap; | 37 | struct msi_bitmap bitmap; |
| 38 | |||
| 39 | struct list_head list; /* support multiple MSI banks */ | ||
| 37 | }; | 40 | }; |
| 38 | 41 | ||
| 39 | #endif /* _POWERPC_SYSDEV_FSL_MSI_H */ | 42 | #endif /* _POWERPC_SYSDEV_FSL_MSI_H */ |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index e1a028c1f18d..356c6a0e1b23 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
| @@ -23,8 +23,9 @@ | |||
| 23 | #include <linux/string.h> | 23 | #include <linux/string.h> |
| 24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
| 25 | #include <linux/bootmem.h> | 25 | #include <linux/bootmem.h> |
| 26 | #include <linux/lmb.h> | 26 | #include <linux/memblock.h> |
| 27 | #include <linux/log2.h> | 27 | #include <linux/log2.h> |
| 28 | #include <linux/slab.h> | ||
| 28 | 29 | ||
| 29 | #include <asm/io.h> | 30 | #include <asm/io.h> |
| 30 | #include <asm/prom.h> | 31 | #include <asm/prom.h> |
| @@ -189,7 +190,7 @@ static void __init setup_pci_atmu(struct pci_controller *hose, | |||
| 189 | pr_info("%s: PCICSRBAR @ 0x%x\n", name, pcicsrbar); | 190 | pr_info("%s: PCICSRBAR @ 0x%x\n", name, pcicsrbar); |
| 190 | 191 | ||
| 191 | /* Setup inbound mem window */ | 192 | /* Setup inbound mem window */ |
| 192 | mem = lmb_end_of_DRAM(); | 193 | mem = memblock_end_of_DRAM(); |
| 193 | sz = min(mem, paddr_lo); | 194 | sz = min(mem, paddr_lo); |
| 194 | mem_log = __ilog2_u64(sz); | 195 | mem_log = __ilog2_u64(sz); |
| 195 | 196 | ||
diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index a7635a993dca..9082eb921ad9 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c | |||
| @@ -60,7 +60,7 @@ static struct platform_suspend_ops pmc_suspend_ops = { | |||
| 60 | 60 | ||
| 61 | static int pmc_probe(struct of_device *ofdev, const struct of_device_id *id) | 61 | static int pmc_probe(struct of_device *ofdev, const struct of_device_id *id) |
| 62 | { | 62 | { |
| 63 | pmc_regs = of_iomap(ofdev->node, 0); | 63 | pmc_regs = of_iomap(ofdev->dev.of_node, 0); |
| 64 | if (!pmc_regs) | 64 | if (!pmc_regs) |
| 65 | return -ENOMEM; | 65 | return -ENOMEM; |
| 66 | 66 | ||
| @@ -76,8 +76,11 @@ static const struct of_device_id pmc_ids[] = { | |||
| 76 | }; | 76 | }; |
| 77 | 77 | ||
| 78 | static struct of_platform_driver pmc_driver = { | 78 | static struct of_platform_driver pmc_driver = { |
| 79 | .driver.name = "fsl-pmc", | 79 | .driver = { |
| 80 | .match_table = pmc_ids, | 80 | .name = "fsl-pmc", |
| 81 | .owner = THIS_MODULE, | ||
| 82 | .of_match_table = pmc_ids, | ||
| 83 | }, | ||
| 81 | .probe = pmc_probe, | 84 | .probe = pmc_probe, |
| 82 | }; | 85 | }; |
| 83 | 86 | ||
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 757a83fe5e59..30e1626b2e85 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
| @@ -1,6 +1,15 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Freescale MPC85xx/MPC86xx RapidIO support | 2 | * Freescale MPC85xx/MPC86xx RapidIO support |
| 3 | * | 3 | * |
| 4 | * Copyright 2009 Sysgo AG | ||
| 5 | * Thomas Moll <thomas.moll@sysgo.com> | ||
| 6 | * - fixed maintenance access routines, check for aligned access | ||
| 7 | * | ||
| 8 | * Copyright 2009 Integrated Device Technology, Inc. | ||
| 9 | * Alex Bounine <alexandre.bounine@idt.com> | ||
| 10 | * - Added Port-Write message handling | ||
| 11 | * - Added Machine Check exception handling | ||
| 12 | * | ||
| 4 | * Copyright (C) 2007, 2008 Freescale Semiconductor, Inc. | 13 | * Copyright (C) 2007, 2008 Freescale Semiconductor, Inc. |
| 5 | * Zhang Wei <wei.zhang@freescale.com> | 14 | * Zhang Wei <wei.zhang@freescale.com> |
| 6 | * | 15 | * |
| @@ -23,19 +32,31 @@ | |||
| 23 | #include <linux/rio_drv.h> | 32 | #include <linux/rio_drv.h> |
| 24 | #include <linux/of_platform.h> | 33 | #include <linux/of_platform.h> |
| 25 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
| 35 | #include <linux/slab.h> | ||
| 36 | #include <linux/kfifo.h> | ||
| 26 | 37 | ||
| 27 | #include <asm/io.h> | 38 | #include <asm/io.h> |
| 39 | #include <asm/machdep.h> | ||
| 40 | #include <asm/uaccess.h> | ||
| 41 | |||
| 42 | #undef DEBUG_PW /* Port-Write debugging */ | ||
| 28 | 43 | ||
| 29 | /* RapidIO definition irq, which read from OF-tree */ | 44 | /* RapidIO definition irq, which read from OF-tree */ |
| 30 | #define IRQ_RIO_BELL(m) (((struct rio_priv *)(m->priv))->bellirq) | 45 | #define IRQ_RIO_BELL(m) (((struct rio_priv *)(m->priv))->bellirq) |
| 31 | #define IRQ_RIO_TX(m) (((struct rio_priv *)(m->priv))->txirq) | 46 | #define IRQ_RIO_TX(m) (((struct rio_priv *)(m->priv))->txirq) |
| 32 | #define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq) | 47 | #define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq) |
| 48 | #define IRQ_RIO_PW(m) (((struct rio_priv *)(m->priv))->pwirq) | ||
| 33 | 49 | ||
| 34 | #define RIO_ATMU_REGS_OFFSET 0x10c00 | 50 | #define RIO_ATMU_REGS_OFFSET 0x10c00 |
| 35 | #define RIO_P_MSG_REGS_OFFSET 0x11000 | 51 | #define RIO_P_MSG_REGS_OFFSET 0x11000 |
| 36 | #define RIO_S_MSG_REGS_OFFSET 0x13000 | 52 | #define RIO_S_MSG_REGS_OFFSET 0x13000 |
| 37 | #define RIO_ESCSR 0x158 | 53 | #define RIO_ESCSR 0x158 |
| 38 | #define RIO_CCSR 0x15c | 54 | #define RIO_CCSR 0x15c |
| 55 | #define RIO_LTLEDCSR 0x0608 | ||
| 56 | #define RIO_LTLEDCSR_IER 0x80000000 | ||
| 57 | #define RIO_LTLEDCSR_PRT 0x01000000 | ||
| 58 | #define RIO_LTLEECSR 0x060c | ||
| 59 | #define RIO_EPWISR 0x10010 | ||
| 39 | #define RIO_ISR_AACR 0x10120 | 60 | #define RIO_ISR_AACR 0x10120 |
| 40 | #define RIO_ISR_AACR_AA 0x1 /* Accept All ID */ | 61 | #define RIO_ISR_AACR_AA 0x1 /* Accept All ID */ |
| 41 | #define RIO_MAINT_WIN_SIZE 0x400000 | 62 | #define RIO_MAINT_WIN_SIZE 0x400000 |
| @@ -54,6 +75,18 @@ | |||
| 54 | #define RIO_MSG_ISR_QFI 0x00000010 | 75 | #define RIO_MSG_ISR_QFI 0x00000010 |
| 55 | #define RIO_MSG_ISR_DIQI 0x00000001 | 76 | #define RIO_MSG_ISR_DIQI 0x00000001 |
| 56 | 77 | ||
| 78 | #define RIO_IPWMR_SEN 0x00100000 | ||
| 79 | #define RIO_IPWMR_QFIE 0x00000100 | ||
| 80 | #define RIO_IPWMR_EIE 0x00000020 | ||
| 81 | #define RIO_IPWMR_CQ 0x00000002 | ||
| 82 | #define RIO_IPWMR_PWE 0x00000001 | ||
| 83 | |||
| 84 | #define RIO_IPWSR_QF 0x00100000 | ||
| 85 | #define RIO_IPWSR_TE 0x00000080 | ||
| 86 | #define RIO_IPWSR_QFI 0x00000010 | ||
| 87 | #define RIO_IPWSR_PWD 0x00000008 | ||
| 88 | #define RIO_IPWSR_PWB 0x00000004 | ||
| 89 | |||
| 57 | #define RIO_MSG_DESC_SIZE 32 | 90 | #define RIO_MSG_DESC_SIZE 32 |
| 58 | #define RIO_MSG_BUFFER_SIZE 4096 | 91 | #define RIO_MSG_BUFFER_SIZE 4096 |
| 59 | #define RIO_MIN_TX_RING_SIZE 2 | 92 | #define RIO_MIN_TX_RING_SIZE 2 |
| @@ -120,7 +153,7 @@ struct rio_msg_regs { | |||
| 120 | u32 pad10[26]; | 153 | u32 pad10[26]; |
| 121 | u32 pwmr; | 154 | u32 pwmr; |
| 122 | u32 pwsr; | 155 | u32 pwsr; |
| 123 | u32 pad11; | 156 | u32 epwqbar; |
| 124 | u32 pwqbar; | 157 | u32 pwqbar; |
| 125 | }; | 158 | }; |
| 126 | 159 | ||
| @@ -159,6 +192,14 @@ struct rio_msg_rx_ring { | |||
| 159 | void *dev_id; | 192 | void *dev_id; |
| 160 | }; | 193 | }; |
| 161 | 194 | ||
| 195 | struct rio_port_write_msg { | ||
| 196 | void *virt; | ||
| 197 | dma_addr_t phys; | ||
| 198 | u32 msg_count; | ||
| 199 | u32 err_count; | ||
| 200 | u32 discard_count; | ||
| 201 | }; | ||
| 202 | |||
| 162 | struct rio_priv { | 203 | struct rio_priv { |
| 163 | struct device *dev; | 204 | struct device *dev; |
| 164 | void __iomem *regs_win; | 205 | void __iomem *regs_win; |
| @@ -171,11 +212,64 @@ struct rio_priv { | |||
| 171 | struct rio_dbell_ring dbell_ring; | 212 | struct rio_dbell_ring dbell_ring; |
| 172 | struct rio_msg_tx_ring msg_tx_ring; | 213 | struct rio_msg_tx_ring msg_tx_ring; |
| 173 | struct rio_msg_rx_ring msg_rx_ring; | 214 | struct rio_msg_rx_ring msg_rx_ring; |
| 215 | struct rio_port_write_msg port_write_msg; | ||
| 174 | int bellirq; | 216 | int bellirq; |
| 175 | int txirq; | 217 | int txirq; |
| 176 | int rxirq; | 218 | int rxirq; |
| 219 | int pwirq; | ||
| 220 | struct work_struct pw_work; | ||
| 221 | struct kfifo pw_fifo; | ||
| 222 | spinlock_t pw_fifo_lock; | ||
| 177 | }; | 223 | }; |
| 178 | 224 | ||
| 225 | #define __fsl_read_rio_config(x, addr, err, op) \ | ||
| 226 | __asm__ __volatile__( \ | ||
| 227 | "1: "op" %1,0(%2)\n" \ | ||
| 228 | " eieio\n" \ | ||
| 229 | "2:\n" \ | ||
| 230 | ".section .fixup,\"ax\"\n" \ | ||
| 231 | "3: li %1,-1\n" \ | ||
| 232 | " li %0,%3\n" \ | ||
| 233 | " b 2b\n" \ | ||
| 234 | ".section __ex_table,\"a\"\n" \ | ||
| 235 | " .align 2\n" \ | ||
| 236 | " .long 1b,3b\n" \ | ||
| 237 | ".text" \ | ||
| 238 | : "=r" (err), "=r" (x) \ | ||
| 239 | : "b" (addr), "i" (-EFAULT), "0" (err)) | ||
| 240 | |||
| 241 | static void __iomem *rio_regs_win; | ||
| 242 | |||
| 243 | static int (*saved_mcheck_exception)(struct pt_regs *regs); | ||
| 244 | |||
| 245 | static int fsl_rio_mcheck_exception(struct pt_regs *regs) | ||
| 246 | { | ||
| 247 | const struct exception_table_entry *entry = NULL; | ||
| 248 | unsigned long reason = (mfspr(SPRN_MCSR) & MCSR_MASK); | ||
| 249 | |||
| 250 | if (reason & MCSR_BUS_RBERR) { | ||
| 251 | reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR)); | ||
| 252 | if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) { | ||
| 253 | /* Check if we are prepared to handle this fault */ | ||
| 254 | entry = search_exception_tables(regs->nip); | ||
| 255 | if (entry) { | ||
| 256 | pr_debug("RIO: %s - MC Exception handled\n", | ||
| 257 | __func__); | ||
| 258 | out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), | ||
| 259 | 0); | ||
| 260 | regs->msr |= MSR_RI; | ||
| 261 | regs->nip = entry->fixup; | ||
| 262 | return 1; | ||
| 263 | } | ||
| 264 | } | ||
| 265 | } | ||
| 266 | |||
| 267 | if (saved_mcheck_exception) | ||
| 268 | return saved_mcheck_exception(regs); | ||
| 269 | else | ||
| 270 | return cur_cpu_spec->machine_check(regs); | ||
| 271 | } | ||
| 272 | |||
| 179 | /** | 273 | /** |
| 180 | * fsl_rio_doorbell_send - Send a MPC85xx doorbell message | 274 | * fsl_rio_doorbell_send - Send a MPC85xx doorbell message |
| 181 | * @mport: RapidIO master port info | 275 | * @mport: RapidIO master port info |
| @@ -276,27 +370,44 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, | |||
| 276 | { | 370 | { |
| 277 | struct rio_priv *priv = mport->priv; | 371 | struct rio_priv *priv = mport->priv; |
| 278 | u8 *data; | 372 | u8 *data; |
| 373 | u32 rval, err = 0; | ||
| 279 | 374 | ||
| 280 | pr_debug | 375 | pr_debug |
| 281 | ("fsl_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n", | 376 | ("fsl_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n", |
| 282 | index, destid, hopcount, offset, len); | 377 | index, destid, hopcount, offset, len); |
| 378 | |||
| 379 | /* 16MB maintenance window possible */ | ||
| 380 | /* allow only aligned access to maintenance registers */ | ||
| 381 | if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) | ||
| 382 | return -EINVAL; | ||
| 383 | |||
| 283 | out_be32(&priv->maint_atmu_regs->rowtar, | 384 | out_be32(&priv->maint_atmu_regs->rowtar, |
| 284 | (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); | 385 | (destid << 22) | (hopcount << 12) | (offset >> 12)); |
| 386 | out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); | ||
| 285 | 387 | ||
| 286 | data = (u8 *) priv->maint_win + offset; | 388 | data = (u8 *) priv->maint_win + (offset & (RIO_MAINT_WIN_SIZE - 1)); |
| 287 | switch (len) { | 389 | switch (len) { |
| 288 | case 1: | 390 | case 1: |
| 289 | *val = in_8((u8 *) data); | 391 | __fsl_read_rio_config(rval, data, err, "lbz"); |
| 290 | break; | 392 | break; |
| 291 | case 2: | 393 | case 2: |
| 292 | *val = in_be16((u16 *) data); | 394 | __fsl_read_rio_config(rval, data, err, "lhz"); |
| 293 | break; | 395 | break; |
| 294 | default: | 396 | case 4: |
| 295 | *val = in_be32((u32 *) data); | 397 | __fsl_read_rio_config(rval, data, err, "lwz"); |
| 296 | break; | 398 | break; |
| 399 | default: | ||
| 400 | return -EINVAL; | ||
| 297 | } | 401 | } |
| 298 | 402 | ||
| 299 | return 0; | 403 | if (err) { |
| 404 | pr_debug("RIO: cfg_read error %d for %x:%x:%x\n", | ||
| 405 | err, destid, hopcount, offset); | ||
| 406 | } | ||
| 407 | |||
| 408 | *val = rval; | ||
| 409 | |||
| 410 | return err; | ||
| 300 | } | 411 | } |
| 301 | 412 | ||
| 302 | /** | 413 | /** |
| @@ -321,10 +432,17 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, | |||
| 321 | pr_debug | 432 | pr_debug |
| 322 | ("fsl_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", | 433 | ("fsl_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", |
| 323 | index, destid, hopcount, offset, len, val); | 434 | index, destid, hopcount, offset, len, val); |
| 435 | |||
| 436 | /* 16MB maintenance windows possible */ | ||
| 437 | /* allow only aligned access to maintenance registers */ | ||
| 438 | if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) | ||
| 439 | return -EINVAL; | ||
| 440 | |||
| 324 | out_be32(&priv->maint_atmu_regs->rowtar, | 441 | out_be32(&priv->maint_atmu_regs->rowtar, |
| 325 | (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); | 442 | (destid << 22) | (hopcount << 12) | (offset >> 12)); |
| 443 | out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); | ||
| 326 | 444 | ||
| 327 | data = (u8 *) priv->maint_win + offset; | 445 | data = (u8 *) priv->maint_win + (offset & (RIO_MAINT_WIN_SIZE - 1)); |
| 328 | switch (len) { | 446 | switch (len) { |
| 329 | case 1: | 447 | case 1: |
| 330 | out_8((u8 *) data, val); | 448 | out_8((u8 *) data, val); |
| @@ -332,9 +450,11 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, | |||
| 332 | case 2: | 450 | case 2: |
| 333 | out_be16((u16 *) data, val); | 451 | out_be16((u16 *) data, val); |
| 334 | break; | 452 | break; |
| 335 | default: | 453 | case 4: |
| 336 | out_be32((u32 *) data, val); | 454 | out_be32((u32 *) data, val); |
| 337 | break; | 455 | break; |
| 456 | default: | ||
| 457 | return -EINVAL; | ||
| 338 | } | 458 | } |
| 339 | 459 | ||
| 340 | return 0; | 460 | return 0; |
| @@ -929,6 +1049,223 @@ static int fsl_rio_doorbell_init(struct rio_mport *mport) | |||
| 929 | return rc; | 1049 | return rc; |
| 930 | } | 1050 | } |
| 931 | 1051 | ||
| 1052 | /** | ||
| 1053 | * fsl_rio_port_write_handler - MPC85xx port write interrupt handler | ||
| 1054 | * @irq: Linux interrupt number | ||
| 1055 | * @dev_instance: Pointer to interrupt-specific data | ||
| 1056 | * | ||
| 1057 | * Handles port write interrupts. Parses a list of registered | ||
| 1058 | * port write event handlers and executes a matching event handler. | ||
| 1059 | */ | ||
| 1060 | static irqreturn_t | ||
| 1061 | fsl_rio_port_write_handler(int irq, void *dev_instance) | ||
| 1062 | { | ||
| 1063 | u32 ipwmr, ipwsr; | ||
| 1064 | struct rio_mport *port = (struct rio_mport *)dev_instance; | ||
| 1065 | struct rio_priv *priv = port->priv; | ||
| 1066 | u32 epwisr, tmp; | ||
| 1067 | |||
| 1068 | ipwmr = in_be32(&priv->msg_regs->pwmr); | ||
| 1069 | ipwsr = in_be32(&priv->msg_regs->pwsr); | ||
| 1070 | |||
| 1071 | epwisr = in_be32(priv->regs_win + RIO_EPWISR); | ||
| 1072 | if (epwisr & 0x80000000) { | ||
| 1073 | tmp = in_be32(priv->regs_win + RIO_LTLEDCSR); | ||
| 1074 | pr_info("RIO_LTLEDCSR = 0x%x\n", tmp); | ||
| 1075 | out_be32(priv->regs_win + RIO_LTLEDCSR, 0); | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | if (!(epwisr & 0x00000001)) | ||
| 1079 | return IRQ_HANDLED; | ||
| 1080 | |||
| 1081 | #ifdef DEBUG_PW | ||
| 1082 | pr_debug("PW Int->IPWMR: 0x%08x IPWSR: 0x%08x (", ipwmr, ipwsr); | ||
| 1083 | if (ipwsr & RIO_IPWSR_QF) | ||
| 1084 | pr_debug(" QF"); | ||
| 1085 | if (ipwsr & RIO_IPWSR_TE) | ||
| 1086 | pr_debug(" TE"); | ||
| 1087 | if (ipwsr & RIO_IPWSR_QFI) | ||
| 1088 | pr_debug(" QFI"); | ||
| 1089 | if (ipwsr & RIO_IPWSR_PWD) | ||
| 1090 | pr_debug(" PWD"); | ||
| 1091 | if (ipwsr & RIO_IPWSR_PWB) | ||
| 1092 | pr_debug(" PWB"); | ||
| 1093 | pr_debug(" )\n"); | ||
| 1094 | #endif | ||
| 1095 | out_be32(&priv->msg_regs->pwsr, | ||
| 1096 | ipwsr & (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD)); | ||
| 1097 | |||
| 1098 | if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) { | ||
| 1099 | priv->port_write_msg.err_count++; | ||
| 1100 | pr_info("RIO: Port-Write Transaction Err (%d)\n", | ||
| 1101 | priv->port_write_msg.err_count); | ||
| 1102 | } | ||
| 1103 | if (ipwsr & RIO_IPWSR_PWD) { | ||
| 1104 | priv->port_write_msg.discard_count++; | ||
| 1105 | pr_info("RIO: Port Discarded Port-Write Msg(s) (%d)\n", | ||
| 1106 | priv->port_write_msg.discard_count); | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | /* Schedule deferred processing if PW was received */ | ||
| 1110 | if (ipwsr & RIO_IPWSR_QFI) { | ||
| 1111 | /* Save PW message (if there is room in FIFO), | ||
| 1112 | * otherwise discard it. | ||
| 1113 | */ | ||
| 1114 | if (kfifo_avail(&priv->pw_fifo) >= RIO_PW_MSG_SIZE) { | ||
| 1115 | priv->port_write_msg.msg_count++; | ||
| 1116 | kfifo_in(&priv->pw_fifo, priv->port_write_msg.virt, | ||
| 1117 | RIO_PW_MSG_SIZE); | ||
| 1118 | } else { | ||
| 1119 | priv->port_write_msg.discard_count++; | ||
| 1120 | pr_info("RIO: ISR Discarded Port-Write Msg(s) (%d)\n", | ||
| 1121 | priv->port_write_msg.discard_count); | ||
| 1122 | } | ||
| 1123 | schedule_work(&priv->pw_work); | ||
| 1124 | } | ||
| 1125 | |||
| 1126 | /* Issue Clear Queue command. This allows another | ||
| 1127 | * port-write to be received. | ||
| 1128 | */ | ||
| 1129 | out_be32(&priv->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ); | ||
| 1130 | |||
| 1131 | return IRQ_HANDLED; | ||
| 1132 | } | ||
| 1133 | |||
| 1134 | static void fsl_pw_dpc(struct work_struct *work) | ||
| 1135 | { | ||
| 1136 | struct rio_priv *priv = container_of(work, struct rio_priv, pw_work); | ||
| 1137 | unsigned long flags; | ||
| 1138 | u32 msg_buffer[RIO_PW_MSG_SIZE/sizeof(u32)]; | ||
| 1139 | |||
| 1140 | /* | ||
| 1141 | * Process port-write messages | ||
| 1142 | */ | ||
| 1143 | spin_lock_irqsave(&priv->pw_fifo_lock, flags); | ||
| 1144 | while (kfifo_out(&priv->pw_fifo, (unsigned char *)msg_buffer, | ||
| 1145 | RIO_PW_MSG_SIZE)) { | ||
| 1146 | /* Process one message */ | ||
| 1147 | spin_unlock_irqrestore(&priv->pw_fifo_lock, flags); | ||
| 1148 | #ifdef DEBUG_PW | ||
| 1149 | { | ||
| 1150 | u32 i; | ||
| 1151 | pr_debug("%s : Port-Write Message:", __func__); | ||
| 1152 | for (i = 0; i < RIO_PW_MSG_SIZE/sizeof(u32); i++) { | ||
| 1153 | if ((i%4) == 0) | ||
| 1154 | pr_debug("\n0x%02x: 0x%08x", i*4, | ||
| 1155 | msg_buffer[i]); | ||
| 1156 | else | ||
| 1157 | pr_debug(" 0x%08x", msg_buffer[i]); | ||
| 1158 | } | ||
| 1159 | pr_debug("\n"); | ||
| 1160 | } | ||
| 1161 | #endif | ||
| 1162 | /* Pass the port-write message to RIO core for processing */ | ||
| 1163 | rio_inb_pwrite_handler((union rio_pw_msg *)msg_buffer); | ||
| 1164 | spin_lock_irqsave(&priv->pw_fifo_lock, flags); | ||
| 1165 | } | ||
| 1166 | spin_unlock_irqrestore(&priv->pw_fifo_lock, flags); | ||
| 1167 | } | ||
| 1168 | |||
| 1169 | /** | ||
| 1170 | * fsl_rio_pw_enable - enable/disable port-write interface init | ||
| 1171 | * @mport: Master port implementing the port write unit | ||
| 1172 | * @enable: 1=enable; 0=disable port-write message handling | ||
| 1173 | */ | ||
| 1174 | static int fsl_rio_pw_enable(struct rio_mport *mport, int enable) | ||
| 1175 | { | ||
| 1176 | struct rio_priv *priv = mport->priv; | ||
| 1177 | u32 rval; | ||
| 1178 | |||
| 1179 | rval = in_be32(&priv->msg_regs->pwmr); | ||
| 1180 | |||
| 1181 | if (enable) | ||
| 1182 | rval |= RIO_IPWMR_PWE; | ||
| 1183 | else | ||
| 1184 | rval &= ~RIO_IPWMR_PWE; | ||
| 1185 | |||
| 1186 | out_be32(&priv->msg_regs->pwmr, rval); | ||
| 1187 | |||
| 1188 | return 0; | ||
| 1189 | } | ||
| 1190 | |||
| 1191 | /** | ||
| 1192 | * fsl_rio_port_write_init - MPC85xx port write interface init | ||
| 1193 | * @mport: Master port implementing the port write unit | ||
| 1194 | * | ||
| 1195 | * Initializes port write unit hardware and DMA buffer | ||
| 1196 | * ring. Called from fsl_rio_setup(). Returns %0 on success | ||
| 1197 | * or %-ENOMEM on failure. | ||
| 1198 | */ | ||
| 1199 | static int fsl_rio_port_write_init(struct rio_mport *mport) | ||
| 1200 | { | ||
| 1201 | struct rio_priv *priv = mport->priv; | ||
| 1202 | int rc = 0; | ||
| 1203 | |||
| 1204 | /* Following configurations require a disabled port write controller */ | ||
| 1205 | out_be32(&priv->msg_regs->pwmr, | ||
| 1206 | in_be32(&priv->msg_regs->pwmr) & ~RIO_IPWMR_PWE); | ||
| 1207 | |||
| 1208 | /* Initialize port write */ | ||
| 1209 | priv->port_write_msg.virt = dma_alloc_coherent(priv->dev, | ||
| 1210 | RIO_PW_MSG_SIZE, | ||
| 1211 | &priv->port_write_msg.phys, GFP_KERNEL); | ||
| 1212 | if (!priv->port_write_msg.virt) { | ||
| 1213 | pr_err("RIO: unable allocate port write queue\n"); | ||
| 1214 | return -ENOMEM; | ||
| 1215 | } | ||
| 1216 | |||
| 1217 | priv->port_write_msg.err_count = 0; | ||
| 1218 | priv->port_write_msg.discard_count = 0; | ||
| 1219 | |||
| 1220 | /* Point dequeue/enqueue pointers at first entry */ | ||
| 1221 | out_be32(&priv->msg_regs->epwqbar, 0); | ||
| 1222 | out_be32(&priv->msg_regs->pwqbar, (u32) priv->port_write_msg.phys); | ||
| 1223 | |||
| 1224 | pr_debug("EIPWQBAR: 0x%08x IPWQBAR: 0x%08x\n", | ||
| 1225 | in_be32(&priv->msg_regs->epwqbar), | ||
| 1226 | in_be32(&priv->msg_regs->pwqbar)); | ||
| 1227 | |||
| 1228 | /* Clear interrupt status IPWSR */ | ||
| 1229 | out_be32(&priv->msg_regs->pwsr, | ||
| 1230 | (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD)); | ||
| 1231 | |||
| 1232 | /* Configure port write contoller for snooping enable all reporting, | ||
| 1233 | clear queue full */ | ||
| 1234 | out_be32(&priv->msg_regs->pwmr, | ||
| 1235 | RIO_IPWMR_SEN | RIO_IPWMR_QFIE | RIO_IPWMR_EIE | RIO_IPWMR_CQ); | ||
| 1236 | |||
| 1237 | |||
| 1238 | /* Hook up port-write handler */ | ||
| 1239 | rc = request_irq(IRQ_RIO_PW(mport), fsl_rio_port_write_handler, 0, | ||
| 1240 | "port-write", (void *)mport); | ||
| 1241 | if (rc < 0) { | ||
| 1242 | pr_err("MPC85xx RIO: unable to request inbound doorbell irq"); | ||
| 1243 | goto err_out; | ||
| 1244 | } | ||
| 1245 | |||
| 1246 | INIT_WORK(&priv->pw_work, fsl_pw_dpc); | ||
| 1247 | spin_lock_init(&priv->pw_fifo_lock); | ||
| 1248 | if (kfifo_alloc(&priv->pw_fifo, RIO_PW_MSG_SIZE * 32, GFP_KERNEL)) { | ||
| 1249 | pr_err("FIFO allocation failed\n"); | ||
| 1250 | rc = -ENOMEM; | ||
| 1251 | goto err_out_irq; | ||
| 1252 | } | ||
| 1253 | |||
| 1254 | pr_debug("IPWMR: 0x%08x IPWSR: 0x%08x\n", | ||
| 1255 | in_be32(&priv->msg_regs->pwmr), | ||
| 1256 | in_be32(&priv->msg_regs->pwsr)); | ||
| 1257 | |||
| 1258 | return rc; | ||
| 1259 | |||
| 1260 | err_out_irq: | ||
| 1261 | free_irq(IRQ_RIO_PW(mport), (void *)mport); | ||
| 1262 | err_out: | ||
| 1263 | dma_free_coherent(priv->dev, RIO_PW_MSG_SIZE, | ||
| 1264 | priv->port_write_msg.virt, | ||
| 1265 | priv->port_write_msg.phys); | ||
| 1266 | return rc; | ||
| 1267 | } | ||
| 1268 | |||
| 932 | static char *cmdline = NULL; | 1269 | static char *cmdline = NULL; |
| 933 | 1270 | ||
| 934 | static int fsl_rio_get_hdid(int index) | 1271 | static int fsl_rio_get_hdid(int index) |
| @@ -1014,41 +1351,41 @@ int fsl_rio_setup(struct of_device *dev) | |||
| 1014 | u64 law_start, law_size; | 1351 | u64 law_start, law_size; |
| 1015 | int paw, aw, sw; | 1352 | int paw, aw, sw; |
| 1016 | 1353 | ||
| 1017 | if (!dev->node) { | 1354 | if (!dev->dev.of_node) { |
| 1018 | dev_err(&dev->dev, "Device OF-Node is NULL"); | 1355 | dev_err(&dev->dev, "Device OF-Node is NULL"); |
| 1019 | return -EFAULT; | 1356 | return -EFAULT; |
| 1020 | } | 1357 | } |
| 1021 | 1358 | ||
| 1022 | rc = of_address_to_resource(dev->node, 0, ®s); | 1359 | rc = of_address_to_resource(dev->dev.of_node, 0, ®s); |
| 1023 | if (rc) { | 1360 | if (rc) { |
| 1024 | dev_err(&dev->dev, "Can't get %s property 'reg'\n", | 1361 | dev_err(&dev->dev, "Can't get %s property 'reg'\n", |
| 1025 | dev->node->full_name); | 1362 | dev->dev.of_node->full_name); |
| 1026 | return -EFAULT; | 1363 | return -EFAULT; |
| 1027 | } | 1364 | } |
| 1028 | dev_info(&dev->dev, "Of-device full name %s\n", dev->node->full_name); | 1365 | dev_info(&dev->dev, "Of-device full name %s\n", dev->dev.of_node->full_name); |
| 1029 | dev_info(&dev->dev, "Regs: %pR\n", ®s); | 1366 | dev_info(&dev->dev, "Regs: %pR\n", ®s); |
| 1030 | 1367 | ||
| 1031 | dt_range = of_get_property(dev->node, "ranges", &rlen); | 1368 | dt_range = of_get_property(dev->dev.of_node, "ranges", &rlen); |
| 1032 | if (!dt_range) { | 1369 | if (!dt_range) { |
| 1033 | dev_err(&dev->dev, "Can't get %s property 'ranges'\n", | 1370 | dev_err(&dev->dev, "Can't get %s property 'ranges'\n", |
| 1034 | dev->node->full_name); | 1371 | dev->dev.of_node->full_name); |
| 1035 | return -EFAULT; | 1372 | return -EFAULT; |
| 1036 | } | 1373 | } |
| 1037 | 1374 | ||
| 1038 | /* Get node address wide */ | 1375 | /* Get node address wide */ |
| 1039 | cell = of_get_property(dev->node, "#address-cells", NULL); | 1376 | cell = of_get_property(dev->dev.of_node, "#address-cells", NULL); |
| 1040 | if (cell) | 1377 | if (cell) |
| 1041 | aw = *cell; | 1378 | aw = *cell; |
| 1042 | else | 1379 | else |
| 1043 | aw = of_n_addr_cells(dev->node); | 1380 | aw = of_n_addr_cells(dev->dev.of_node); |
| 1044 | /* Get node size wide */ | 1381 | /* Get node size wide */ |
| 1045 | cell = of_get_property(dev->node, "#size-cells", NULL); | 1382 | cell = of_get_property(dev->dev.of_node, "#size-cells", NULL); |
| 1046 | if (cell) | 1383 | if (cell) |
| 1047 | sw = *cell; | 1384 | sw = *cell; |
| 1048 | else | 1385 | else |
| 1049 | sw = of_n_size_cells(dev->node); | 1386 | sw = of_n_size_cells(dev->dev.of_node); |
| 1050 | /* Get parent address wide wide */ | 1387 | /* Get parent address wide wide */ |
| 1051 | paw = of_n_addr_cells(dev->node); | 1388 | paw = of_n_addr_cells(dev->dev.of_node); |
| 1052 | 1389 | ||
| 1053 | law_start = of_read_number(dt_range + aw, paw); | 1390 | law_start = of_read_number(dt_range + aw, paw); |
| 1054 | law_size = of_read_number(dt_range + aw + paw, sw); | 1391 | law_size = of_read_number(dt_range + aw + paw, sw); |
| @@ -1056,7 +1393,7 @@ int fsl_rio_setup(struct of_device *dev) | |||
| 1056 | dev_info(&dev->dev, "LAW start 0x%016llx, size 0x%016llx.\n", | 1393 | dev_info(&dev->dev, "LAW start 0x%016llx, size 0x%016llx.\n", |
| 1057 | law_start, law_size); | 1394 | law_start, law_size); |
| 1058 | 1395 | ||
| 1059 | ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL); | 1396 | ops = kzalloc(sizeof(struct rio_ops), GFP_KERNEL); |
| 1060 | if (!ops) { | 1397 | if (!ops) { |
| 1061 | rc = -ENOMEM; | 1398 | rc = -ENOMEM; |
| 1062 | goto err_ops; | 1399 | goto err_ops; |
| @@ -1066,6 +1403,7 @@ int fsl_rio_setup(struct of_device *dev) | |||
| 1066 | ops->cread = fsl_rio_config_read; | 1403 | ops->cread = fsl_rio_config_read; |
| 1067 | ops->cwrite = fsl_rio_config_write; | 1404 | ops->cwrite = fsl_rio_config_write; |
| 1068 | ops->dsend = fsl_rio_doorbell_send; | 1405 | ops->dsend = fsl_rio_doorbell_send; |
| 1406 | ops->pwenable = fsl_rio_pw_enable; | ||
| 1069 | 1407 | ||
| 1070 | port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL); | 1408 | port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL); |
| 1071 | if (!port) { | 1409 | if (!port) { |
| @@ -1088,11 +1426,12 @@ int fsl_rio_setup(struct of_device *dev) | |||
| 1088 | port->iores.flags = IORESOURCE_MEM; | 1426 | port->iores.flags = IORESOURCE_MEM; |
| 1089 | port->iores.name = "rio_io_win"; | 1427 | port->iores.name = "rio_io_win"; |
| 1090 | 1428 | ||
| 1091 | priv->bellirq = irq_of_parse_and_map(dev->node, 2); | 1429 | priv->pwirq = irq_of_parse_and_map(dev->dev.of_node, 0); |
| 1092 | priv->txirq = irq_of_parse_and_map(dev->node, 3); | 1430 | priv->bellirq = irq_of_parse_and_map(dev->dev.of_node, 2); |
| 1093 | priv->rxirq = irq_of_parse_and_map(dev->node, 4); | 1431 | priv->txirq = irq_of_parse_and_map(dev->dev.of_node, 3); |
| 1094 | dev_info(&dev->dev, "bellirq: %d, txirq: %d, rxirq %d\n", priv->bellirq, | 1432 | priv->rxirq = irq_of_parse_and_map(dev->dev.of_node, 4); |
| 1095 | priv->txirq, priv->rxirq); | 1433 | dev_info(&dev->dev, "pwirq: %d, bellirq: %d, txirq: %d, rxirq %d\n", |
| 1434 | priv->pwirq, priv->bellirq, priv->txirq, priv->rxirq); | ||
| 1096 | 1435 | ||
| 1097 | rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); | 1436 | rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); |
| 1098 | rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0); | 1437 | rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0); |
| @@ -1108,6 +1447,7 @@ int fsl_rio_setup(struct of_device *dev) | |||
| 1108 | rio_register_mport(port); | 1447 | rio_register_mport(port); |
| 1109 | 1448 | ||
| 1110 | priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1); | 1449 | priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1); |
| 1450 | rio_regs_win = priv->regs_win; | ||
| 1111 | 1451 | ||
| 1112 | /* Probe the master port phy type */ | 1452 | /* Probe the master port phy type */ |
| 1113 | ccsr = in_be32(priv->regs_win + RIO_CCSR); | 1453 | ccsr = in_be32(priv->regs_win + RIO_CCSR); |
| @@ -1165,7 +1505,8 @@ int fsl_rio_setup(struct of_device *dev) | |||
| 1165 | 1505 | ||
| 1166 | /* Configure maintenance transaction window */ | 1506 | /* Configure maintenance transaction window */ |
| 1167 | out_be32(&priv->maint_atmu_regs->rowbar, law_start >> 12); | 1507 | out_be32(&priv->maint_atmu_regs->rowbar, law_start >> 12); |
| 1168 | out_be32(&priv->maint_atmu_regs->rowar, 0x80077015); /* 4M */ | 1508 | out_be32(&priv->maint_atmu_regs->rowar, |
| 1509 | 0x80077000 | (ilog2(RIO_MAINT_WIN_SIZE) - 1)); | ||
| 1169 | 1510 | ||
| 1170 | priv->maint_win = ioremap(law_start, RIO_MAINT_WIN_SIZE); | 1511 | priv->maint_win = ioremap(law_start, RIO_MAINT_WIN_SIZE); |
| 1171 | 1512 | ||
| @@ -1174,6 +1515,12 @@ int fsl_rio_setup(struct of_device *dev) | |||
| 1174 | (law_start + RIO_MAINT_WIN_SIZE) >> 12); | 1515 | (law_start + RIO_MAINT_WIN_SIZE) >> 12); |
| 1175 | out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b); /* 4k */ | 1516 | out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b); /* 4k */ |
| 1176 | fsl_rio_doorbell_init(port); | 1517 | fsl_rio_doorbell_init(port); |
| 1518 | fsl_rio_port_write_init(port); | ||
| 1519 | |||
| 1520 | saved_mcheck_exception = ppc_md.machine_check_exception; | ||
| 1521 | ppc_md.machine_check_exception = fsl_rio_mcheck_exception; | ||
| 1522 | /* Ensure that RFXE is set */ | ||
| 1523 | mtspr(SPRN_HID1, (mfspr(SPRN_HID1) | 0x20000)); | ||
| 1177 | 1524 | ||
| 1178 | return 0; | 1525 | return 0; |
| 1179 | err: | 1526 | err: |
| @@ -1194,7 +1541,7 @@ static int __devinit fsl_of_rio_rpn_probe(struct of_device *dev, | |||
| 1194 | { | 1541 | { |
| 1195 | int rc; | 1542 | int rc; |
| 1196 | printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n", | 1543 | printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n", |
| 1197 | dev->node->full_name); | 1544 | dev->dev.of_node->full_name); |
| 1198 | 1545 | ||
| 1199 | rc = fsl_rio_setup(dev); | 1546 | rc = fsl_rio_setup(dev); |
| 1200 | if (rc) | 1547 | if (rc) |
| @@ -1214,8 +1561,11 @@ static const struct of_device_id fsl_of_rio_rpn_ids[] = { | |||
| 1214 | }; | 1561 | }; |
| 1215 | 1562 | ||
| 1216 | static struct of_platform_driver fsl_of_rio_rpn_driver = { | 1563 | static struct of_platform_driver fsl_of_rio_rpn_driver = { |
| 1217 | .name = "fsl-of-rio", | 1564 | .driver = { |
| 1218 | .match_table = fsl_of_rio_rpn_ids, | 1565 | .name = "fsl-of-rio", |
| 1566 | .owner = THIS_MODULE, | ||
| 1567 | .of_match_table = fsl_of_rio_rpn_ids, | ||
| 1568 | }, | ||
| 1219 | .probe = fsl_of_rio_rpn_probe, | 1569 | .probe = fsl_of_rio_rpn_probe, |
| 1220 | }; | 1570 | }; |
| 1221 | 1571 | ||
diff --git a/arch/powerpc/sysdev/micropatch.c b/arch/powerpc/sysdev/micropatch.c index d8d602840757..c0bb76ef7242 100644 --- a/arch/powerpc/sysdev/micropatch.c +++ b/arch/powerpc/sysdev/micropatch.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | * also relocates SMC2, but this would require additional changes | 4 | * also relocates SMC2, but this would require additional changes |
| 5 | * to uart.c, so I am holding off on that for a moment. | 5 | * to uart.c, so I am holding off on that for a moment. |
| 6 | */ | 6 | */ |
| 7 | #include <linux/init.h> | ||
| 7 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
| 8 | #include <linux/sched.h> | 9 | #include <linux/sched.h> |
| 9 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
| @@ -16,6 +17,7 @@ | |||
| 16 | #include <asm/page.h> | 17 | #include <asm/page.h> |
| 17 | #include <asm/pgtable.h> | 18 | #include <asm/pgtable.h> |
| 18 | #include <asm/8xx_immap.h> | 19 | #include <asm/8xx_immap.h> |
| 20 | #include <asm/cpm.h> | ||
| 19 | #include <asm/cpm1.h> | 21 | #include <asm/cpm1.h> |
| 20 | 22 | ||
| 21 | /* | 23 | /* |
| @@ -24,7 +26,7 @@ | |||
| 24 | 26 | ||
| 25 | #ifdef CONFIG_I2C_SPI_UCODE_PATCH | 27 | #ifdef CONFIG_I2C_SPI_UCODE_PATCH |
| 26 | 28 | ||
| 27 | uint patch_2000[] = { | 29 | static uint patch_2000[] __initdata = { |
| 28 | 0x7FFFEFD9, | 30 | 0x7FFFEFD9, |
| 29 | 0x3FFD0000, | 31 | 0x3FFD0000, |
| 30 | 0x7FFB49F7, | 32 | 0x7FFB49F7, |
| @@ -143,7 +145,7 @@ uint patch_2000[] = { | |||
| 143 | 0x5F8247F8 | 145 | 0x5F8247F8 |
| 144 | }; | 146 | }; |
| 145 | 147 | ||
| 146 | uint patch_2f00[] = { | 148 | static uint patch_2f00[] __initdata = { |
| 147 | 0x3E303430, | 149 | 0x3E303430, |
| 148 | 0x34343737, | 150 | 0x34343737, |
| 149 | 0xABF7BF9B, | 151 | 0xABF7BF9B, |
| @@ -182,7 +184,7 @@ uint patch_2f00[] = { | |||
| 182 | 184 | ||
| 183 | #ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH | 185 | #ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH |
| 184 | 186 | ||
| 185 | uint patch_2000[] = { | 187 | static uint patch_2000[] __initdata = { |
| 186 | 0x3fff0000, | 188 | 0x3fff0000, |
| 187 | 0x3ffd0000, | 189 | 0x3ffd0000, |
| 188 | 0x3ffb0000, | 190 | 0x3ffb0000, |
| @@ -505,7 +507,7 @@ uint patch_2000[] = { | |||
| 505 | 0x6079e2bb | 507 | 0x6079e2bb |
| 506 | }; | 508 | }; |
| 507 | 509 | ||
| 508 | uint patch_2f00[] = { | 510 | static uint patch_2f00[] __initdata = { |
| 509 | 0x30303030, | 511 | 0x30303030, |
| 510 | 0x3e3e3434, | 512 | 0x3e3e3434, |
| 511 | 0xabbf9b99, | 513 | 0xabbf9b99, |
| @@ -572,7 +574,7 @@ uint patch_2f00[] = { | |||
| 572 | 0xf22f3f23 | 574 | 0xf22f3f23 |
| 573 | }; | 575 | }; |
| 574 | 576 | ||
| 575 | uint patch_2e00[] = { | 577 | static uint patch_2e00[] __initdata = { |
| 576 | 0x27eeeeee, | 578 | 0x27eeeeee, |
| 577 | 0xeeeeeeee, | 579 | 0xeeeeeeee, |
| 578 | 0xeeeeeeee, | 580 | 0xeeeeeeee, |
| @@ -598,7 +600,7 @@ uint patch_2e00[] = { | |||
| 598 | 600 | ||
| 599 | #ifdef CONFIG_USB_SOF_UCODE_PATCH | 601 | #ifdef CONFIG_USB_SOF_UCODE_PATCH |
| 600 | 602 | ||
| 601 | uint patch_2000[] = { | 603 | static uint patch_2000[] __initdata = { |
| 602 | 0x7fff0000, | 604 | 0x7fff0000, |
| 603 | 0x7ffd0000, | 605 | 0x7ffd0000, |
| 604 | 0x7ffb0000, | 606 | 0x7ffb0000, |
| @@ -613,21 +615,25 @@ uint patch_2000[] = { | |||
| 613 | 0x60750000 | 615 | 0x60750000 |
| 614 | }; | 616 | }; |
| 615 | 617 | ||
| 616 | uint patch_2f00[] = { | 618 | static uint patch_2f00[] __initdata = { |
| 617 | 0x3030304c, | 619 | 0x3030304c, |
| 618 | 0xcab9e441, | 620 | 0xcab9e441, |
| 619 | 0xa1aaf220 | 621 | 0xa1aaf220 |
| 620 | }; | 622 | }; |
| 621 | #endif | 623 | #endif |
| 622 | 624 | ||
| 623 | void | 625 | void __init cpm_load_patch(cpm8xx_t *cp) |
| 624 | cpm_load_patch(cpm8xx_t *cp) | ||
| 625 | { | 626 | { |
| 626 | volatile uint *dp; /* Dual-ported RAM. */ | 627 | volatile uint *dp; /* Dual-ported RAM. */ |
| 627 | volatile cpm8xx_t *commproc; | 628 | volatile cpm8xx_t *commproc; |
| 629 | #if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \ | ||
| 630 | defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) | ||
| 628 | volatile iic_t *iip; | 631 | volatile iic_t *iip; |
| 629 | volatile spi_t *spp; | 632 | volatile struct spi_pram *spp; |
| 633 | #ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH | ||
| 630 | volatile smc_uart_t *smp; | 634 | volatile smc_uart_t *smp; |
| 635 | #endif | ||
| 636 | #endif | ||
| 631 | int i; | 637 | int i; |
| 632 | 638 | ||
| 633 | commproc = cp; | 639 | commproc = cp; |
| @@ -668,8 +674,8 @@ cpm_load_patch(cpm8xx_t *cp) | |||
| 668 | /* Put SPI above the IIC, also 32-byte aligned. | 674 | /* Put SPI above the IIC, also 32-byte aligned. |
| 669 | */ | 675 | */ |
| 670 | i = (RPBASE + sizeof(iic_t) + 31) & ~31; | 676 | i = (RPBASE + sizeof(iic_t) + 31) & ~31; |
| 671 | spp = (spi_t *)&commproc->cp_dparam[PROFF_SPI]; | 677 | spp = (struct spi_pram *)&commproc->cp_dparam[PROFF_SPI]; |
| 672 | spp->spi_rpbase = i; | 678 | spp->rpbase = i; |
| 673 | 679 | ||
| 674 | # if defined(CONFIG_I2C_SPI_UCODE_PATCH) | 680 | # if defined(CONFIG_I2C_SPI_UCODE_PATCH) |
| 675 | commproc->cp_cpmcr1 = 0x802a; | 681 | commproc->cp_cpmcr1 = 0x802a; |
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c index ee1c0e1cf4a7..83f519655fac 100644 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
| 16 | #include <linux/of_gpio.h> | 16 | #include <linux/of_gpio.h> |
| 17 | #include <linux/gpio.h> | 17 | #include <linux/gpio.h> |
| 18 | #include <linux/slab.h> | ||
| 19 | #include <linux/irq.h> | ||
| 18 | 20 | ||
| 19 | #define MPC8XXX_GPIO_PINS 32 | 21 | #define MPC8XXX_GPIO_PINS 32 |
| 20 | 22 | ||
| @@ -34,6 +36,7 @@ struct mpc8xxx_gpio_chip { | |||
| 34 | * open drain mode safely | 36 | * open drain mode safely |
| 35 | */ | 37 | */ |
| 36 | u32 data; | 38 | u32 data; |
| 39 | struct irq_host *irq; | ||
| 37 | }; | 40 | }; |
| 38 | 41 | ||
| 39 | static inline u32 mpc8xxx_gpio2mask(unsigned int gpio) | 42 | static inline u32 mpc8xxx_gpio2mask(unsigned int gpio) |
| @@ -127,12 +130,136 @@ static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val | |||
| 127 | return 0; | 130 | return 0; |
| 128 | } | 131 | } |
| 129 | 132 | ||
| 133 | static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | ||
| 134 | { | ||
| 135 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | ||
| 136 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm); | ||
| 137 | |||
| 138 | if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS) | ||
| 139 | return irq_create_mapping(mpc8xxx_gc->irq, offset); | ||
| 140 | else | ||
| 141 | return -ENXIO; | ||
| 142 | } | ||
| 143 | |||
| 144 | static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc) | ||
| 145 | { | ||
| 146 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_desc_data(desc); | ||
| 147 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
| 148 | unsigned int mask; | ||
| 149 | |||
| 150 | mask = in_be32(mm->regs + GPIO_IER) & in_be32(mm->regs + GPIO_IMR); | ||
| 151 | if (mask) | ||
| 152 | generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, | ||
| 153 | 32 - ffs(mask))); | ||
| 154 | } | ||
| 155 | |||
| 156 | static void mpc8xxx_irq_unmask(unsigned int virq) | ||
| 157 | { | ||
| 158 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq); | ||
| 159 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
| 160 | unsigned long flags; | ||
| 161 | |||
| 162 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
| 163 | |||
| 164 | setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(virq))); | ||
| 165 | |||
| 166 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
| 167 | } | ||
| 168 | |||
| 169 | static void mpc8xxx_irq_mask(unsigned int virq) | ||
| 170 | { | ||
| 171 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq); | ||
| 172 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
| 173 | unsigned long flags; | ||
| 174 | |||
| 175 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
| 176 | |||
| 177 | clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(virq))); | ||
| 178 | |||
| 179 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
| 180 | } | ||
| 181 | |||
| 182 | static void mpc8xxx_irq_ack(unsigned int virq) | ||
| 183 | { | ||
| 184 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq); | ||
| 185 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
| 186 | |||
| 187 | out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(virq_to_hw(virq))); | ||
| 188 | } | ||
| 189 | |||
| 190 | static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type) | ||
| 191 | { | ||
| 192 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq); | ||
| 193 | struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; | ||
| 194 | unsigned long flags; | ||
| 195 | |||
| 196 | switch (flow_type) { | ||
| 197 | case IRQ_TYPE_EDGE_FALLING: | ||
| 198 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
| 199 | setbits32(mm->regs + GPIO_ICR, | ||
| 200 | mpc8xxx_gpio2mask(virq_to_hw(virq))); | ||
| 201 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
| 202 | break; | ||
| 203 | |||
| 204 | case IRQ_TYPE_EDGE_BOTH: | ||
| 205 | spin_lock_irqsave(&mpc8xxx_gc->lock, flags); | ||
| 206 | clrbits32(mm->regs + GPIO_ICR, | ||
| 207 | mpc8xxx_gpio2mask(virq_to_hw(virq))); | ||
| 208 | spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); | ||
| 209 | break; | ||
| 210 | |||
| 211 | default: | ||
| 212 | return -EINVAL; | ||
| 213 | } | ||
| 214 | |||
| 215 | return 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | static struct irq_chip mpc8xxx_irq_chip = { | ||
| 219 | .name = "mpc8xxx-gpio", | ||
| 220 | .unmask = mpc8xxx_irq_unmask, | ||
| 221 | .mask = mpc8xxx_irq_mask, | ||
| 222 | .ack = mpc8xxx_irq_ack, | ||
| 223 | .set_type = mpc8xxx_irq_set_type, | ||
| 224 | }; | ||
| 225 | |||
| 226 | static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq, | ||
| 227 | irq_hw_number_t hw) | ||
| 228 | { | ||
| 229 | set_irq_chip_data(virq, h->host_data); | ||
| 230 | set_irq_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq); | ||
| 231 | set_irq_type(virq, IRQ_TYPE_NONE); | ||
| 232 | |||
| 233 | return 0; | ||
| 234 | } | ||
| 235 | |||
| 236 | static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct, | ||
| 237 | const u32 *intspec, unsigned int intsize, | ||
| 238 | irq_hw_number_t *out_hwirq, | ||
| 239 | unsigned int *out_flags) | ||
| 240 | |||
| 241 | { | ||
| 242 | /* interrupt sense values coming from the device tree equal either | ||
| 243 | * EDGE_FALLING or EDGE_BOTH | ||
| 244 | */ | ||
| 245 | *out_hwirq = intspec[0]; | ||
| 246 | *out_flags = intspec[1]; | ||
| 247 | |||
| 248 | return 0; | ||
| 249 | } | ||
| 250 | |||
| 251 | static struct irq_host_ops mpc8xxx_gpio_irq_ops = { | ||
| 252 | .map = mpc8xxx_gpio_irq_map, | ||
| 253 | .xlate = mpc8xxx_gpio_irq_xlate, | ||
| 254 | }; | ||
| 255 | |||
| 130 | static void __init mpc8xxx_add_controller(struct device_node *np) | 256 | static void __init mpc8xxx_add_controller(struct device_node *np) |
| 131 | { | 257 | { |
| 132 | struct mpc8xxx_gpio_chip *mpc8xxx_gc; | 258 | struct mpc8xxx_gpio_chip *mpc8xxx_gc; |
| 133 | struct of_mm_gpio_chip *mm_gc; | 259 | struct of_mm_gpio_chip *mm_gc; |
| 134 | struct of_gpio_chip *of_gc; | 260 | struct of_gpio_chip *of_gc; |
| 135 | struct gpio_chip *gc; | 261 | struct gpio_chip *gc; |
| 262 | unsigned hwirq; | ||
| 136 | int ret; | 263 | int ret; |
| 137 | 264 | ||
| 138 | mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL); | 265 | mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL); |
| @@ -157,11 +284,32 @@ static void __init mpc8xxx_add_controller(struct device_node *np) | |||
| 157 | else | 284 | else |
| 158 | gc->get = mpc8xxx_gpio_get; | 285 | gc->get = mpc8xxx_gpio_get; |
| 159 | gc->set = mpc8xxx_gpio_set; | 286 | gc->set = mpc8xxx_gpio_set; |
| 287 | gc->to_irq = mpc8xxx_gpio_to_irq; | ||
| 160 | 288 | ||
| 161 | ret = of_mm_gpiochip_add(np, mm_gc); | 289 | ret = of_mm_gpiochip_add(np, mm_gc); |
| 162 | if (ret) | 290 | if (ret) |
| 163 | goto err; | 291 | goto err; |
| 164 | 292 | ||
| 293 | hwirq = irq_of_parse_and_map(np, 0); | ||
| 294 | if (hwirq == NO_IRQ) | ||
| 295 | goto skip_irq; | ||
| 296 | |||
| 297 | mpc8xxx_gc->irq = | ||
| 298 | irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS, | ||
| 299 | &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS); | ||
| 300 | if (!mpc8xxx_gc->irq) | ||
| 301 | goto skip_irq; | ||
| 302 | |||
| 303 | mpc8xxx_gc->irq->host_data = mpc8xxx_gc; | ||
| 304 | |||
| 305 | /* ack and mask all irqs */ | ||
| 306 | out_be32(mm_gc->regs + GPIO_IER, 0xffffffff); | ||
| 307 | out_be32(mm_gc->regs + GPIO_IMR, 0); | ||
| 308 | |||
| 309 | set_irq_data(hwirq, mpc8xxx_gc); | ||
| 310 | set_irq_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade); | ||
| 311 | |||
| 312 | skip_irq: | ||
| 165 | return; | 313 | return; |
| 166 | 314 | ||
| 167 | err: | 315 | err: |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 339e8a3e26d2..20b73c025a45 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/bootmem.h> | 26 | #include <linux/bootmem.h> |
| 27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
| 28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
| 29 | #include <linux/slab.h> | ||
| 29 | 30 | ||
| 30 | #include <asm/ptrace.h> | 31 | #include <asm/ptrace.h> |
| 31 | #include <asm/signal.h> | 32 | #include <asm/signal.h> |
| @@ -567,12 +568,12 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic) | |||
| 567 | #endif /* CONFIG_MPIC_U3_HT_IRQS */ | 568 | #endif /* CONFIG_MPIC_U3_HT_IRQS */ |
| 568 | 569 | ||
| 569 | #ifdef CONFIG_SMP | 570 | #ifdef CONFIG_SMP |
| 570 | static int irq_choose_cpu(const cpumask_t *mask) | 571 | static int irq_choose_cpu(const struct cpumask *mask) |
| 571 | { | 572 | { |
| 572 | int cpuid; | 573 | int cpuid; |
| 573 | 574 | ||
| 574 | if (cpumask_equal(mask, cpu_all_mask)) { | 575 | if (cpumask_equal(mask, cpu_all_mask)) { |
| 575 | static int irq_rover; | 576 | static int irq_rover = 0; |
| 576 | static DEFINE_RAW_SPINLOCK(irq_rover_lock); | 577 | static DEFINE_RAW_SPINLOCK(irq_rover_lock); |
| 577 | unsigned long flags; | 578 | unsigned long flags; |
| 578 | 579 | ||
| @@ -580,15 +581,11 @@ static int irq_choose_cpu(const cpumask_t *mask) | |||
| 580 | do_round_robin: | 581 | do_round_robin: |
| 581 | raw_spin_lock_irqsave(&irq_rover_lock, flags); | 582 | raw_spin_lock_irqsave(&irq_rover_lock, flags); |
| 582 | 583 | ||
| 583 | while (!cpu_online(irq_rover)) { | 584 | irq_rover = cpumask_next(irq_rover, cpu_online_mask); |
| 584 | if (++irq_rover >= NR_CPUS) | 585 | if (irq_rover >= nr_cpu_ids) |
| 585 | irq_rover = 0; | 586 | irq_rover = cpumask_first(cpu_online_mask); |
| 586 | } | 587 | |
| 587 | cpuid = irq_rover; | 588 | cpuid = irq_rover; |
| 588 | do { | ||
| 589 | if (++irq_rover >= NR_CPUS) | ||
| 590 | irq_rover = 0; | ||
| 591 | } while (!cpu_online(irq_rover)); | ||
| 592 | 589 | ||
| 593 | raw_spin_unlock_irqrestore(&irq_rover_lock, flags); | 590 | raw_spin_unlock_irqrestore(&irq_rover_lock, flags); |
| 594 | } else { | 591 | } else { |
| @@ -600,7 +597,7 @@ static int irq_choose_cpu(const cpumask_t *mask) | |||
| 600 | return get_hard_smp_processor_id(cpuid); | 597 | return get_hard_smp_processor_id(cpuid); |
| 601 | } | 598 | } |
| 602 | #else | 599 | #else |
| 603 | static int irq_choose_cpu(const cpumask_t *mask) | 600 | static int irq_choose_cpu(const struct cpumask *mask) |
| 604 | { | 601 | { |
| 605 | return hard_smp_processor_id(); | 602 | return hard_smp_processor_id(); |
| 606 | } | 603 | } |
| @@ -813,12 +810,16 @@ int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask) | |||
| 813 | 810 | ||
| 814 | mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid); | 811 | mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid); |
| 815 | } else { | 812 | } else { |
| 816 | cpumask_t tmp; | 813 | cpumask_var_t tmp; |
| 817 | 814 | ||
| 818 | cpumask_and(&tmp, cpumask, cpu_online_mask); | 815 | alloc_cpumask_var(&tmp, GFP_KERNEL); |
| 816 | |||
| 817 | cpumask_and(tmp, cpumask, cpu_online_mask); | ||
| 819 | 818 | ||
| 820 | mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), | 819 | mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), |
| 821 | mpic_physmask(cpus_addr(tmp)[0])); | 820 | mpic_physmask(cpumask_bits(tmp)[0])); |
| 821 | |||
| 822 | free_cpumask_var(tmp); | ||
| 822 | } | 823 | } |
| 823 | 824 | ||
| 824 | return 0; | 825 | return 0; |
| @@ -1478,21 +1479,6 @@ void mpic_teardown_this_cpu(int secondary) | |||
| 1478 | } | 1479 | } |
| 1479 | 1480 | ||
| 1480 | 1481 | ||
| 1481 | void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask) | ||
| 1482 | { | ||
| 1483 | struct mpic *mpic = mpic_primary; | ||
| 1484 | |||
| 1485 | BUG_ON(mpic == NULL); | ||
| 1486 | |||
| 1487 | #ifdef DEBUG_IPI | ||
| 1488 | DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no); | ||
| 1489 | #endif | ||
| 1490 | |||
| 1491 | mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) + | ||
| 1492 | ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE), | ||
| 1493 | mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0])); | ||
| 1494 | } | ||
| 1495 | |||
| 1496 | static unsigned int _mpic_get_one_irq(struct mpic *mpic, int reg) | 1482 | static unsigned int _mpic_get_one_irq(struct mpic *mpic, int reg) |
| 1497 | { | 1483 | { |
| 1498 | u32 src; | 1484 | u32 src; |
| @@ -1588,8 +1574,25 @@ void mpic_request_ipis(void) | |||
| 1588 | } | 1574 | } |
| 1589 | } | 1575 | } |
| 1590 | 1576 | ||
| 1577 | static void mpic_send_ipi(unsigned int ipi_no, const struct cpumask *cpu_mask) | ||
| 1578 | { | ||
| 1579 | struct mpic *mpic = mpic_primary; | ||
| 1580 | |||
| 1581 | BUG_ON(mpic == NULL); | ||
| 1582 | |||
| 1583 | #ifdef DEBUG_IPI | ||
| 1584 | DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no); | ||
| 1585 | #endif | ||
| 1586 | |||
| 1587 | mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) + | ||
| 1588 | ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE), | ||
| 1589 | mpic_physmask(cpumask_bits(cpu_mask)[0])); | ||
| 1590 | } | ||
| 1591 | |||
| 1591 | void smp_mpic_message_pass(int target, int msg) | 1592 | void smp_mpic_message_pass(int target, int msg) |
| 1592 | { | 1593 | { |
| 1594 | cpumask_var_t tmp; | ||
| 1595 | |||
| 1593 | /* make sure we're sending something that translates to an IPI */ | 1596 | /* make sure we're sending something that translates to an IPI */ |
| 1594 | if ((unsigned int)msg > 3) { | 1597 | if ((unsigned int)msg > 3) { |
| 1595 | printk("SMP %d: smp_message_pass: unknown msg %d\n", | 1598 | printk("SMP %d: smp_message_pass: unknown msg %d\n", |
| @@ -1598,13 +1601,17 @@ void smp_mpic_message_pass(int target, int msg) | |||
| 1598 | } | 1601 | } |
| 1599 | switch (target) { | 1602 | switch (target) { |
| 1600 | case MSG_ALL: | 1603 | case MSG_ALL: |
| 1601 | mpic_send_ipi(msg, 0xffffffff); | 1604 | mpic_send_ipi(msg, cpu_online_mask); |
| 1602 | break; | 1605 | break; |
| 1603 | case MSG_ALL_BUT_SELF: | 1606 | case MSG_ALL_BUT_SELF: |
| 1604 | mpic_send_ipi(msg, 0xffffffff & ~(1 << smp_processor_id())); | 1607 | alloc_cpumask_var(&tmp, GFP_NOWAIT); |
| 1608 | cpumask_andnot(tmp, cpu_online_mask, | ||
| 1609 | cpumask_of(smp_processor_id())); | ||
| 1610 | mpic_send_ipi(msg, tmp); | ||
| 1611 | free_cpumask_var(tmp); | ||
| 1605 | break; | 1612 | break; |
| 1606 | default: | 1613 | default: |
| 1607 | mpic_send_ipi(msg, 1 << target); | 1614 | mpic_send_ipi(msg, cpumask_of(target)); |
| 1608 | break; | 1615 | break; |
| 1609 | } | 1616 | } |
| 1610 | } | 1617 | } |
| @@ -1615,7 +1622,7 @@ int __init smp_mpic_probe(void) | |||
| 1615 | 1622 | ||
| 1616 | DBG("smp_mpic_probe()...\n"); | 1623 | DBG("smp_mpic_probe()...\n"); |
| 1617 | 1624 | ||
| 1618 | nr_cpus = cpus_weight(cpu_possible_map); | 1625 | nr_cpus = cpumask_weight(cpu_possible_mask); |
| 1619 | 1626 | ||
| 1620 | DBG("nr_cpus: %d\n", nr_cpus); | 1627 | DBG("nr_cpus: %d\n", nr_cpus); |
| 1621 | 1628 | ||
| @@ -1659,7 +1666,7 @@ static int mpic_resume(struct sys_device *dev) | |||
| 1659 | mpic->save_data[i].dest); | 1666 | mpic->save_data[i].dest); |
| 1660 | 1667 | ||
| 1661 | #ifdef CONFIG_MPIC_U3_HT_IRQS | 1668 | #ifdef CONFIG_MPIC_U3_HT_IRQS |
| 1662 | { | 1669 | if (mpic->fixups) { |
| 1663 | struct mpic_irq_fixup *fixup = &mpic->fixups[i]; | 1670 | struct mpic_irq_fixup *fixup = &mpic->fixups[i]; |
| 1664 | 1671 | ||
| 1665 | if (fixup->base) { | 1672 | if (fixup->base) { |
diff --git a/arch/powerpc/sysdev/msi_bitmap.c b/arch/powerpc/sysdev/msi_bitmap.c index 5a32cbef9b6c..5287e95cec3a 100644 --- a/arch/powerpc/sysdev/msi_bitmap.c +++ b/arch/powerpc/sysdev/msi_bitmap.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | * | 8 | * |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/slab.h> | ||
| 11 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
| 12 | #include <linux/bitmap.h> | 13 | #include <linux/bitmap.h> |
| 13 | #include <asm/msi_bitmap.h> | 14 | #include <asm/msi_bitmap.h> |
diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c index 1456015a22d8..198f288570cc 100644 --- a/arch/powerpc/sysdev/mv64x60_pci.c +++ b/arch/powerpc/sysdev/mv64x60_pci.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | #define MV64X60_VAL_LEN_MAX 11 | 24 | #define MV64X60_VAL_LEN_MAX 11 |
| 25 | #define MV64X60_PCICFG_CPCI_HOTSWAP 0x68 | 25 | #define MV64X60_PCICFG_CPCI_HOTSWAP 0x68 |
| 26 | 26 | ||
| 27 | static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, | 27 | static ssize_t mv64x60_hs_reg_read(struct file *filp, struct kobject *kobj, |
| 28 | struct bin_attribute *attr, char *buf, | 28 | struct bin_attribute *attr, char *buf, |
| 29 | loff_t off, size_t count) | 29 | loff_t off, size_t count) |
| 30 | { | 30 | { |
| @@ -45,7 +45,7 @@ static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, | |||
| 45 | return sprintf(buf, "0x%08x\n", v); | 45 | return sprintf(buf, "0x%08x\n", v); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | static ssize_t mv64x60_hs_reg_write(struct kobject *kobj, | 48 | static ssize_t mv64x60_hs_reg_write(struct file *filp, struct kobject *kobj, |
| 49 | struct bin_attribute *attr, char *buf, | 49 | struct bin_attribute *attr, char *buf, |
| 50 | loff_t off, size_t count) | 50 | loff_t off, size_t count) |
| 51 | { | 51 | { |
diff --git a/arch/powerpc/sysdev/of_rtc.c b/arch/powerpc/sysdev/of_rtc.c index 3d54450640c1..c9e803f3e267 100644 --- a/arch/powerpc/sysdev/of_rtc.c +++ b/arch/powerpc/sysdev/of_rtc.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/of.h> | 12 | #include <linux/of.h> |
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/of_platform.h> | 14 | #include <linux/of_platform.h> |
| 15 | #include <linux/slab.h> | ||
| 15 | 16 | ||
| 16 | static __initdata struct { | 17 | static __initdata struct { |
| 17 | const char *compatible; | 18 | const char *compatible; |
diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c index aaa915998eb6..d07137a07d75 100644 --- a/arch/powerpc/sysdev/pmi.c +++ b/arch/powerpc/sysdev/pmi.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | */ | 25 | */ |
| 26 | 26 | ||
| 27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
| 28 | #include <linux/slab.h> | ||
| 28 | #include <linux/completion.h> | 29 | #include <linux/completion.h> |
| 29 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
| 30 | #include <linux/workqueue.h> | 31 | #include <linux/workqueue.h> |
| @@ -123,7 +124,7 @@ static void pmi_notify_handlers(struct work_struct *work) | |||
| 123 | static int pmi_of_probe(struct of_device *dev, | 124 | static int pmi_of_probe(struct of_device *dev, |
| 124 | const struct of_device_id *match) | 125 | const struct of_device_id *match) |
| 125 | { | 126 | { |
| 126 | struct device_node *np = dev->node; | 127 | struct device_node *np = dev->dev.of_node; |
| 127 | int rc; | 128 | int rc; |
| 128 | 129 | ||
| 129 | if (data) { | 130 | if (data) { |
| @@ -205,11 +206,12 @@ static int pmi_of_remove(struct of_device *dev) | |||
| 205 | } | 206 | } |
| 206 | 207 | ||
| 207 | static struct of_platform_driver pmi_of_platform_driver = { | 208 | static struct of_platform_driver pmi_of_platform_driver = { |
| 208 | .match_table = pmi_match, | ||
| 209 | .probe = pmi_of_probe, | 209 | .probe = pmi_of_probe, |
| 210 | .remove = pmi_of_remove, | 210 | .remove = pmi_of_remove, |
| 211 | .driver = { | 211 | .driver = { |
| 212 | .name = "pmi", | 212 | .name = "pmi", |
| 213 | .owner = THIS_MODULE, | ||
| 214 | .of_match_table = pmi_match, | ||
| 213 | }, | 215 | }, |
| 214 | }; | 216 | }; |
| 215 | 217 | ||
diff --git a/arch/powerpc/sysdev/ppc4xx_gpio.c b/arch/powerpc/sysdev/ppc4xx_gpio.c index 110efe2a54fc..3812fc366bec 100644 --- a/arch/powerpc/sysdev/ppc4xx_gpio.c +++ b/arch/powerpc/sysdev/ppc4xx_gpio.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/of_gpio.h> | 29 | #include <linux/of_gpio.h> |
| 30 | #include <linux/gpio.h> | 30 | #include <linux/gpio.h> |
| 31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
| 32 | #include <linux/slab.h> | ||
| 32 | 33 | ||
| 33 | #define GPIO_MASK(gpio) (0x80000000 >> (gpio)) | 34 | #define GPIO_MASK(gpio) (0x80000000 >> (gpio)) |
| 34 | #define GPIO_MASK2(gpio) (0xc0000000 >> ((gpio) * 2)) | 35 | #define GPIO_MASK2(gpio) (0xc0000000 >> ((gpio) * 2)) |
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 8aa33021e50b..156aa7d36258 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/of.h> | 24 | #include <linux/of.h> |
| 25 | #include <linux/bootmem.h> | 25 | #include <linux/bootmem.h> |
| 26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
| 27 | #include <linux/slab.h> | ||
| 27 | 28 | ||
| 28 | #include <asm/io.h> | 29 | #include <asm/io.h> |
| 29 | #include <asm/pci-bridge.h> | 30 | #include <asm/pci-bridge.h> |
| @@ -973,6 +974,123 @@ static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata = | |||
| 973 | .setup_utl = ppc460ex_pciex_init_utl, | 974 | .setup_utl = ppc460ex_pciex_init_utl, |
| 974 | }; | 975 | }; |
| 975 | 976 | ||
| 977 | static int __init ppc460sx_pciex_core_init(struct device_node *np) | ||
| 978 | { | ||
| 979 | /* HSS drive amplitude */ | ||
| 980 | mtdcri(SDR0, PESDR0_460SX_HSSL0DAMP, 0xB9843211); | ||
| 981 | mtdcri(SDR0, PESDR0_460SX_HSSL1DAMP, 0xB9843211); | ||
| 982 | mtdcri(SDR0, PESDR0_460SX_HSSL2DAMP, 0xB9843211); | ||
| 983 | mtdcri(SDR0, PESDR0_460SX_HSSL3DAMP, 0xB9843211); | ||
| 984 | mtdcri(SDR0, PESDR0_460SX_HSSL4DAMP, 0xB9843211); | ||
| 985 | mtdcri(SDR0, PESDR0_460SX_HSSL5DAMP, 0xB9843211); | ||
| 986 | mtdcri(SDR0, PESDR0_460SX_HSSL6DAMP, 0xB9843211); | ||
| 987 | mtdcri(SDR0, PESDR0_460SX_HSSL7DAMP, 0xB9843211); | ||
| 988 | |||
| 989 | mtdcri(SDR0, PESDR1_460SX_HSSL0DAMP, 0xB9843211); | ||
| 990 | mtdcri(SDR0, PESDR1_460SX_HSSL1DAMP, 0xB9843211); | ||
| 991 | mtdcri(SDR0, PESDR1_460SX_HSSL2DAMP, 0xB9843211); | ||
| 992 | mtdcri(SDR0, PESDR1_460SX_HSSL3DAMP, 0xB9843211); | ||
| 993 | |||
| 994 | mtdcri(SDR0, PESDR2_460SX_HSSL0DAMP, 0xB9843211); | ||
| 995 | mtdcri(SDR0, PESDR2_460SX_HSSL1DAMP, 0xB9843211); | ||
| 996 | mtdcri(SDR0, PESDR2_460SX_HSSL2DAMP, 0xB9843211); | ||
| 997 | mtdcri(SDR0, PESDR2_460SX_HSSL3DAMP, 0xB9843211); | ||
| 998 | |||
| 999 | /* HSS TX pre-emphasis */ | ||
| 1000 | mtdcri(SDR0, PESDR0_460SX_HSSL0COEFA, 0xDCB98987); | ||
| 1001 | mtdcri(SDR0, PESDR0_460SX_HSSL1COEFA, 0xDCB98987); | ||
| 1002 | mtdcri(SDR0, PESDR0_460SX_HSSL2COEFA, 0xDCB98987); | ||
| 1003 | mtdcri(SDR0, PESDR0_460SX_HSSL3COEFA, 0xDCB98987); | ||
| 1004 | mtdcri(SDR0, PESDR0_460SX_HSSL4COEFA, 0xDCB98987); | ||
| 1005 | mtdcri(SDR0, PESDR0_460SX_HSSL5COEFA, 0xDCB98987); | ||
| 1006 | mtdcri(SDR0, PESDR0_460SX_HSSL6COEFA, 0xDCB98987); | ||
| 1007 | mtdcri(SDR0, PESDR0_460SX_HSSL7COEFA, 0xDCB98987); | ||
| 1008 | |||
| 1009 | mtdcri(SDR0, PESDR1_460SX_HSSL0COEFA, 0xDCB98987); | ||
| 1010 | mtdcri(SDR0, PESDR1_460SX_HSSL1COEFA, 0xDCB98987); | ||
| 1011 | mtdcri(SDR0, PESDR1_460SX_HSSL2COEFA, 0xDCB98987); | ||
| 1012 | mtdcri(SDR0, PESDR1_460SX_HSSL3COEFA, 0xDCB98987); | ||
| 1013 | |||
| 1014 | mtdcri(SDR0, PESDR2_460SX_HSSL0COEFA, 0xDCB98987); | ||
| 1015 | mtdcri(SDR0, PESDR2_460SX_HSSL1COEFA, 0xDCB98987); | ||
| 1016 | mtdcri(SDR0, PESDR2_460SX_HSSL2COEFA, 0xDCB98987); | ||
| 1017 | mtdcri(SDR0, PESDR2_460SX_HSSL3COEFA, 0xDCB98987); | ||
| 1018 | |||
| 1019 | /* HSS TX calibration control */ | ||
| 1020 | mtdcri(SDR0, PESDR0_460SX_HSSL1CALDRV, 0x22222222); | ||
| 1021 | mtdcri(SDR0, PESDR1_460SX_HSSL1CALDRV, 0x22220000); | ||
| 1022 | mtdcri(SDR0, PESDR2_460SX_HSSL1CALDRV, 0x22220000); | ||
| 1023 | |||
| 1024 | /* HSS TX slew control */ | ||
| 1025 | mtdcri(SDR0, PESDR0_460SX_HSSSLEW, 0xFFFFFFFF); | ||
| 1026 | mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000); | ||
| 1027 | mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000); | ||
| 1028 | |||
| 1029 | udelay(100); | ||
| 1030 | |||
| 1031 | /* De-assert PLLRESET */ | ||
| 1032 | dcri_clrset(SDR0, PESDR0_PLLLCT2, 0x00000100, 0); | ||
| 1033 | |||
| 1034 | /* Reset DL, UTL, GPL before configuration */ | ||
| 1035 | mtdcri(SDR0, PESDR0_460SX_RCSSET, | ||
| 1036 | PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); | ||
| 1037 | mtdcri(SDR0, PESDR1_460SX_RCSSET, | ||
| 1038 | PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); | ||
| 1039 | mtdcri(SDR0, PESDR2_460SX_RCSSET, | ||
| 1040 | PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); | ||
| 1041 | |||
| 1042 | udelay(100); | ||
| 1043 | |||
| 1044 | /* | ||
| 1045 | * If bifurcation is not enabled, u-boot would have disabled the | ||
| 1046 | * third PCIe port | ||
| 1047 | */ | ||
| 1048 | if (((mfdcri(SDR0, PESDR1_460SX_HSSCTLSET) & 0x00000001) == | ||
| 1049 | 0x00000001)) { | ||
| 1050 | printk(KERN_INFO "PCI: PCIE bifurcation setup successfully.\n"); | ||
| 1051 | printk(KERN_INFO "PCI: Total 3 PCIE ports are present\n"); | ||
| 1052 | return 3; | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | printk(KERN_INFO "PCI: Total 2 PCIE ports are present\n"); | ||
| 1056 | return 2; | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | ||
| 1060 | { | ||
| 1061 | |||
| 1062 | if (port->endpoint) | ||
| 1063 | dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, | ||
| 1064 | 0x01000000, 0); | ||
| 1065 | else | ||
| 1066 | dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, | ||
| 1067 | 0, 0x01000000); | ||
| 1068 | |||
| 1069 | /*Gen-1*/ | ||
| 1070 | mtdcri(SDR0, port->sdr_base + PESDRn_460SX_RCEI, 0x08000000); | ||
| 1071 | |||
| 1072 | dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, | ||
| 1073 | (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL), | ||
| 1074 | PESDRx_RCSSET_RSTPYN); | ||
| 1075 | |||
| 1076 | port->has_ibpre = 1; | ||
| 1077 | |||
| 1078 | return 0; | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port) | ||
| 1082 | { | ||
| 1083 | /* Max 128 Bytes */ | ||
| 1084 | out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000); | ||
| 1085 | return 0; | ||
| 1086 | } | ||
| 1087 | |||
| 1088 | static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { | ||
| 1089 | .core_init = ppc460sx_pciex_core_init, | ||
| 1090 | .port_init_hw = ppc460sx_pciex_init_port_hw, | ||
| 1091 | .setup_utl = ppc460sx_pciex_init_utl, | ||
| 1092 | }; | ||
| 1093 | |||
| 976 | #endif /* CONFIG_44x */ | 1094 | #endif /* CONFIG_44x */ |
| 977 | 1095 | ||
| 978 | #ifdef CONFIG_40x | 1096 | #ifdef CONFIG_40x |
| @@ -1088,6 +1206,8 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np) | |||
| 1088 | } | 1206 | } |
| 1089 | if (of_device_is_compatible(np, "ibm,plb-pciex-460ex")) | 1207 | if (of_device_is_compatible(np, "ibm,plb-pciex-460ex")) |
| 1090 | ppc4xx_pciex_hwops = &ppc460ex_pcie_hwops; | 1208 | ppc4xx_pciex_hwops = &ppc460ex_pcie_hwops; |
| 1209 | if (of_device_is_compatible(np, "ibm,plb-pciex-460sx")) | ||
| 1210 | ppc4xx_pciex_hwops = &ppc460sx_pcie_hwops; | ||
| 1091 | #endif /* CONFIG_44x */ | 1211 | #endif /* CONFIG_44x */ |
| 1092 | #ifdef CONFIG_40x | 1212 | #ifdef CONFIG_40x |
| 1093 | if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) | 1213 | if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) |
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/sysdev/ppc4xx_pci.h index d04e40b306fb..56d9e5deccbf 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.h +++ b/arch/powerpc/sysdev/ppc4xx_pci.h | |||
| @@ -324,6 +324,64 @@ | |||
| 324 | #define PESDR0_460EX_IHS2 0x036D | 324 | #define PESDR0_460EX_IHS2 0x036D |
| 325 | 325 | ||
| 326 | /* | 326 | /* |
| 327 | * 460SX addtional DCRs | ||
| 328 | */ | ||
| 329 | #define PESDRn_460SX_RCEI 0x02 | ||
| 330 | |||
| 331 | #define PESDR0_460SX_HSSL0DAMP 0x320 | ||
| 332 | #define PESDR0_460SX_HSSL1DAMP 0x321 | ||
| 333 | #define PESDR0_460SX_HSSL2DAMP 0x322 | ||
| 334 | #define PESDR0_460SX_HSSL3DAMP 0x323 | ||
| 335 | #define PESDR0_460SX_HSSL4DAMP 0x324 | ||
| 336 | #define PESDR0_460SX_HSSL5DAMP 0x325 | ||
| 337 | #define PESDR0_460SX_HSSL6DAMP 0x326 | ||
| 338 | #define PESDR0_460SX_HSSL7DAMP 0x327 | ||
| 339 | |||
| 340 | #define PESDR1_460SX_HSSL0DAMP 0x354 | ||
| 341 | #define PESDR1_460SX_HSSL1DAMP 0x355 | ||
| 342 | #define PESDR1_460SX_HSSL2DAMP 0x356 | ||
| 343 | #define PESDR1_460SX_HSSL3DAMP 0x357 | ||
| 344 | |||
| 345 | #define PESDR2_460SX_HSSL0DAMP 0x384 | ||
| 346 | #define PESDR2_460SX_HSSL1DAMP 0x385 | ||
| 347 | #define PESDR2_460SX_HSSL2DAMP 0x386 | ||
| 348 | #define PESDR2_460SX_HSSL3DAMP 0x387 | ||
| 349 | |||
| 350 | #define PESDR0_460SX_HSSL0COEFA 0x328 | ||
| 351 | #define PESDR0_460SX_HSSL1COEFA 0x329 | ||
| 352 | #define PESDR0_460SX_HSSL2COEFA 0x32A | ||
| 353 | #define PESDR0_460SX_HSSL3COEFA 0x32B | ||
| 354 | #define PESDR0_460SX_HSSL4COEFA 0x32C | ||
| 355 | #define PESDR0_460SX_HSSL5COEFA 0x32D | ||
| 356 | #define PESDR0_460SX_HSSL6COEFA 0x32E | ||
| 357 | #define PESDR0_460SX_HSSL7COEFA 0x32F | ||
| 358 | |||
| 359 | #define PESDR1_460SX_HSSL0COEFA 0x358 | ||
| 360 | #define PESDR1_460SX_HSSL1COEFA 0x359 | ||
| 361 | #define PESDR1_460SX_HSSL2COEFA 0x35A | ||
| 362 | #define PESDR1_460SX_HSSL3COEFA 0x35B | ||
| 363 | |||
| 364 | #define PESDR2_460SX_HSSL0COEFA 0x388 | ||
| 365 | #define PESDR2_460SX_HSSL1COEFA 0x389 | ||
| 366 | #define PESDR2_460SX_HSSL2COEFA 0x38A | ||
| 367 | #define PESDR2_460SX_HSSL3COEFA 0x38B | ||
| 368 | |||
| 369 | #define PESDR0_460SX_HSSL1CALDRV 0x339 | ||
| 370 | #define PESDR1_460SX_HSSL1CALDRV 0x361 | ||
| 371 | #define PESDR2_460SX_HSSL1CALDRV 0x391 | ||
| 372 | |||
| 373 | #define PESDR0_460SX_HSSSLEW 0x338 | ||
| 374 | #define PESDR1_460SX_HSSSLEW 0x360 | ||
| 375 | #define PESDR2_460SX_HSSSLEW 0x390 | ||
| 376 | |||
| 377 | #define PESDR0_460SX_HSSCTLSET 0x31E | ||
| 378 | #define PESDR1_460SX_HSSCTLSET 0x352 | ||
| 379 | #define PESDR2_460SX_HSSCTLSET 0x382 | ||
| 380 | |||
| 381 | #define PESDR0_460SX_RCSSET 0x304 | ||
| 382 | #define PESDR1_460SX_RCSSET 0x344 | ||
| 383 | #define PESDR2_460SX_RCSSET 0x374 | ||
| 384 | /* | ||
| 327 | * Of the above, some are common offsets from the base | 385 | * Of the above, some are common offsets from the base |
| 328 | */ | 386 | */ |
| 329 | #define PESDRn_UTLSET1 0x00 | 387 | #define PESDRn_UTLSET1 0x00 |
diff --git a/arch/powerpc/sysdev/ppc4xx_soc.c b/arch/powerpc/sysdev/ppc4xx_soc.c index 5c014350bf16..d3d6ce3c33b4 100644 --- a/arch/powerpc/sysdev/ppc4xx_soc.c +++ b/arch/powerpc/sysdev/ppc4xx_soc.c | |||
| @@ -191,11 +191,31 @@ static int __init ppc4xx_l2c_probe(void) | |||
| 191 | arch_initcall(ppc4xx_l2c_probe); | 191 | arch_initcall(ppc4xx_l2c_probe); |
| 192 | 192 | ||
| 193 | /* | 193 | /* |
| 194 | * At present, this routine just applies a system reset. | 194 | * Apply a system reset. Alternatively a board specific value may be |
| 195 | * provided via the "reset-type" property in the cpu node. | ||
| 195 | */ | 196 | */ |
| 196 | void ppc4xx_reset_system(char *cmd) | 197 | void ppc4xx_reset_system(char *cmd) |
| 197 | { | 198 | { |
| 198 | mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_RST_SYSTEM); | 199 | struct device_node *np; |
| 200 | u32 reset_type = DBCR0_RST_SYSTEM; | ||
| 201 | const u32 *prop; | ||
| 202 | |||
| 203 | np = of_find_node_by_type(NULL, "cpu"); | ||
| 204 | if (np) { | ||
| 205 | prop = of_get_property(np, "reset-type", NULL); | ||
| 206 | |||
| 207 | /* | ||
| 208 | * Check if property exists and if it is in range: | ||
| 209 | * 1 - PPC4xx core reset | ||
| 210 | * 2 - PPC4xx chip reset | ||
| 211 | * 3 - PPC4xx system reset (default) | ||
| 212 | */ | ||
| 213 | if ((prop) && ((prop[0] >= 1) && (prop[0] <= 3))) | ||
| 214 | reset_type = prop[0] << 28; | ||
| 215 | } | ||
| 216 | |||
| 217 | mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | reset_type); | ||
| 218 | |||
| 199 | while (1) | 219 | while (1) |
| 200 | ; /* Just in case the reset doesn't work */ | 220 | ; /* Just in case the reset doesn't work */ |
| 201 | } | 221 | } |
diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c index 8e7a7767dd5c..dc8f8d618074 100644 --- a/arch/powerpc/sysdev/qe_lib/gpio.c +++ b/arch/powerpc/sysdev/qe_lib/gpio.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
| 20 | #include <linux/of_gpio.h> | 20 | #include <linux/of_gpio.h> |
| 21 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
| 22 | #include <linux/slab.h> | ||
| 22 | #include <asm/qe.h> | 23 | #include <asm/qe.h> |
| 23 | 24 | ||
| 24 | struct qe_gpio_chip { | 25 | struct qe_gpio_chip { |
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 149393c02c3f..093e0ae1a941 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c | |||
| @@ -669,8 +669,11 @@ static const struct of_device_id qe_ids[] = { | |||
| 669 | }; | 669 | }; |
| 670 | 670 | ||
| 671 | static struct of_platform_driver qe_driver = { | 671 | static struct of_platform_driver qe_driver = { |
| 672 | .driver.name = "fsl-qe", | 672 | .driver = { |
| 673 | .match_table = qe_ids, | 673 | .name = "fsl-qe", |
| 674 | .owner = THIS_MODULE, | ||
| 675 | .of_match_table = qe_ids, | ||
| 676 | }, | ||
| 674 | .probe = qe_probe, | 677 | .probe = qe_probe, |
| 675 | .resume = qe_resume, | 678 | .resume = qe_resume, |
| 676 | }; | 679 | }; |
diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c index ebb442ea1917..fa589b21dbcd 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc.c +++ b/arch/powerpc/sysdev/qe_lib/ucc.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
| 18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
| 19 | #include <linux/slab.h> | ||
| 20 | #include <linux/stddef.h> | 19 | #include <linux/stddef.h> |
| 21 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
| 22 | #include <linux/module.h> | 21 | #include <linux/module.h> |
diff --git a/arch/powerpc/sysdev/simple_gpio.c b/arch/powerpc/sysdev/simple_gpio.c index 43c4569e24b7..d5fb173e588c 100644 --- a/arch/powerpc/sysdev/simple_gpio.c +++ b/arch/powerpc/sysdev/simple_gpio.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/of.h> | 21 | #include <linux/of.h> |
| 22 | #include <linux/of_gpio.h> | 22 | #include <linux/of_gpio.h> |
| 23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
| 24 | #include <linux/slab.h> | ||
| 24 | #include <asm/prom.h> | 25 | #include <asm/prom.h> |
| 25 | #include "simple_gpio.h" | 26 | #include "simple_gpio.h" |
| 26 | 27 | ||
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c index 595034cfb85a..0ab9281e49ae 100644 --- a/arch/powerpc/sysdev/tsi108_pci.c +++ b/arch/powerpc/sysdev/tsi108_pci.c | |||
| @@ -24,7 +24,6 @@ | |||
| 24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
| 25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| 26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
| 27 | #include <linux/slab.h> | ||
| 28 | #include <linux/irq.h> | 27 | #include <linux/irq.h> |
| 29 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
| 30 | 29 | ||
