diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-11 16:31:41 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-11 16:31:41 -0800 |
commit | 5a62f995446be44811fefa48f91f9efb7ea172d7 (patch) | |
tree | e297371f0d513dc6278bb67d582d2216eb7d74ed /drivers | |
parent | f1d6d6cd9029daa7e7d4a0b14347b5392320f22a (diff) | |
parent | 5d7d8072edc11080a7cf6cc37c9f4e61ca1e93c9 (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (72 commits)
powerpc/pseries: Fix build of topology stuff without CONFIG_NUMA
powerpc/pseries: Fix VPHN build errors on non-SMP systems
powerpc/83xx: add mpc8308_p1m DMA controller device-tree node
powerpc/83xx: add DMA controller to mpc8308 device-tree node
powerpc/512x: try to free dma descriptors in case of allocation failure
powerpc/512x: add MPC8308 dma support
powerpc/512x: fix the hanged dma transfer issue
powerpc/512x: scatter/gather dma fix
powerpc/powermac: Make auto-loading of therm_pm72 possible
of/address: Use propper endianess in get_flags
powerpc/pci: Use printf extension %pR for struct resource
powerpc: Remove unnecessary casts of void ptr
powerpc: Disable VPHN polling during a suspend operation
powerpc/pseries: Poll VPA for topology changes and update NUMA maps
powerpc: iommu: Add device name to iommu error printks
powerpc: Record vma->phys_addr in ioremap()
powerpc: Update compat_arch_ptrace
powerpc: Fix PPC_PTRACE_SETHWDEBUG on PPC_BOOK3S
powerpc/time: printk time stamp init not correct
powerpc: Minor cleanups for machdep.h
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/hvc_vio.c | 2 | ||||
-rw-r--r-- | drivers/dma/Kconfig | 2 | ||||
-rw-r--r-- | drivers/dma/mpc512x_dma.c | 187 | ||||
-rw-r--r-- | drivers/macintosh/macio_asic.c | 7 | ||||
-rw-r--r-- | drivers/macintosh/therm_pm72.c | 30 | ||||
-rw-r--r-- | drivers/ps3/Makefile | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc-cmos.c | 3 |
7 files changed, 135 insertions, 98 deletions
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c index 27370e99c66..5e2f52b3332 100644 --- a/drivers/char/hvc_vio.c +++ b/drivers/char/hvc_vio.c @@ -39,7 +39,7 @@ #include "hvc_console.h" -char hvc_driver_name[] = "hvc_console"; +static const char hvc_driver_name[] = "hvc_console"; static struct vio_device_id hvc_driver_table[] __devinitdata = { {"serial", "hvterm1"}, diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 6ee23592700..ef138731c0e 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -109,7 +109,7 @@ config FSL_DMA config MPC512X_DMA tristate "Freescale MPC512x built-in DMA engine support" - depends on PPC_MPC512x + depends on PPC_MPC512x || PPC_MPC831x select DMA_ENGINE ---help--- Enable support for the Freescale MPC512x built-in DMA engine. diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index 4e9cbf30059..59c270192cc 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -1,6 +1,7 @@ /* * Copyright (C) Freescale Semicondutor, Inc. 2007, 2008. * Copyright (C) Semihalf 2009 + * Copyright (C) Ilya Yanok, Emcraft Systems 2010 * * Written by Piotr Ziecik <kosmo@semihalf.com>. Hardware description * (defines, structures and comments) was taken from MPC5121 DMA driver @@ -70,6 +71,8 @@ #define MPC_DMA_DMAES_SBE (1 << 1) #define MPC_DMA_DMAES_DBE (1 << 0) +#define MPC_DMA_DMAGPOR_SNOOP_ENABLE (1 << 6) + #define MPC_DMA_TSIZE_1 0x00 #define MPC_DMA_TSIZE_2 0x01 #define MPC_DMA_TSIZE_4 0x02 @@ -104,7 +107,10 @@ struct __attribute__ ((__packed__)) mpc_dma_regs { /* 0x30 */ u32 dmahrsh; /* DMA hw request status high(ch63~32) */ u32 dmahrsl; /* DMA hardware request status low(ch31~0) */ - u32 dmaihsa; /* DMA interrupt high select AXE(ch63~32) */ + union { + u32 dmaihsa; /* DMA interrupt high select AXE(ch63~32) */ + u32 dmagpor; /* (General purpose register on MPC8308) */ + }; u32 dmailsa; /* DMA interrupt low select AXE(ch31~0) */ /* 0x40 ~ 0xff */ u32 reserve0[48]; /* Reserved */ @@ -195,7 +201,9 @@ struct mpc_dma { struct mpc_dma_regs __iomem *regs; struct mpc_dma_tcd __iomem *tcd; int irq; + int irq2; uint error_status; + int is_mpc8308; /* Lock for error_status field in this structure */ spinlock_t error_status_lock; @@ -252,11 +260,13 @@ static void mpc_dma_execute(struct mpc_dma_chan *mchan) prev = mdesc; } - prev->tcd->start = 0; prev->tcd->int_maj = 1; /* Send first descriptor in chain into hardware */ memcpy_toio(&mdma->tcd[cid], first->tcd, sizeof(struct mpc_dma_tcd)); + + if (first != prev) + mdma->tcd[cid].e_sg = 1; out_8(&mdma->regs->dmassrt, cid); } @@ -274,6 +284,9 @@ static void mpc_dma_irq_process(struct mpc_dma *mdma, u32 is, u32 es, int off) spin_lock(&mchan->lock); + out_8(&mdma->regs->dmacint, ch + off); + out_8(&mdma->regs->dmacerr, ch + off); + /* Check error status */ if (es & (1 << ch)) list_for_each_entry(mdesc, &mchan->active, node) @@ -302,36 +315,68 @@ static irqreturn_t mpc_dma_irq(int irq, void *data) spin_unlock(&mdma->error_status_lock); /* Handle interrupt on each channel */ - mpc_dma_irq_process(mdma, in_be32(&mdma->regs->dmainth), + if (mdma->dma.chancnt > 32) { + mpc_dma_irq_process(mdma, in_be32(&mdma->regs->dmainth), in_be32(&mdma->regs->dmaerrh), 32); + } mpc_dma_irq_process(mdma, in_be32(&mdma->regs->dmaintl), in_be32(&mdma->regs->dmaerrl), 0); - /* Ack interrupt on all channels */ - out_be32(&mdma->regs->dmainth, 0xFFFFFFFF); - out_be32(&mdma->regs->dmaintl, 0xFFFFFFFF); - out_be32(&mdma->regs->dmaerrh, 0xFFFFFFFF); - out_be32(&mdma->regs->dmaerrl, 0xFFFFFFFF); - /* Schedule tasklet */ tasklet_schedule(&mdma->tasklet); return IRQ_HANDLED; } -/* DMA Tasklet */ -static void mpc_dma_tasklet(unsigned long data) +/* proccess completed descriptors */ +static void mpc_dma_process_completed(struct mpc_dma *mdma) { - struct mpc_dma *mdma = (void *)data; dma_cookie_t last_cookie = 0; struct mpc_dma_chan *mchan; struct mpc_dma_desc *mdesc; struct dma_async_tx_descriptor *desc; unsigned long flags; LIST_HEAD(list); - uint es; int i; + for (i = 0; i < mdma->dma.chancnt; i++) { + mchan = &mdma->channels[i]; + + /* Get all completed descriptors */ + spin_lock_irqsave(&mchan->lock, flags); + if (!list_empty(&mchan->completed)) + list_splice_tail_init(&mchan->completed, &list); + spin_unlock_irqrestore(&mchan->lock, flags); + + if (list_empty(&list)) + continue; + + /* Execute callbacks and run dependencies */ + list_for_each_entry(mdesc, &list, node) { + desc = &mdesc->desc; + + if (desc->callback) + desc->callback(desc->callback_param); + + last_cookie = desc->cookie; + dma_run_dependencies(desc); + } + + /* Free descriptors */ + spin_lock_irqsave(&mchan->lock, flags); + list_splice_tail_init(&list, &mchan->free); + mchan->completed_cookie = last_cookie; + spin_unlock_irqrestore(&mchan->lock, flags); + } +} + +/* DMA Tasklet */ +static void mpc_dma_tasklet(unsigned long data) +{ + struct mpc_dma *mdma = (void *)data; + unsigned long flags; + uint es; + spin_lock_irqsave(&mdma->error_status_lock, flags); es = mdma->error_status; mdma->error_status = 0; @@ -370,35 +415,7 @@ static void mpc_dma_tasklet(unsigned long data) dev_err(mdma->dma.dev, "- Destination Bus Error\n"); } - for (i = 0; i < mdma->dma.chancnt; i++) { - mchan = &mdma->channels[i]; - - /* Get all completed descriptors */ - spin_lock_irqsave(&mchan->lock, flags); - if (!list_empty(&mchan->completed)) - list_splice_tail_init(&mchan->completed, &list); - spin_unlock_irqrestore(&mchan->lock, flags); - - if (list_empty(&list)) - continue; - - /* Execute callbacks and run dependencies */ - list_for_each_entry(mdesc, &list, node) { - desc = &mdesc->desc; - - if (desc->callback) - desc->callback(desc->callback_param); - - last_cookie = desc->cookie; - dma_run_dependencies(desc); - } - - /* Free descriptors */ - spin_lock_irqsave(&mchan->lock, flags); - list_splice_tail_init(&list, &mchan->free); - mchan->completed_cookie = last_cookie; - spin_unlock_irqrestore(&mchan->lock, flags); - } + mpc_dma_process_completed(mdma); } /* Submit descriptor to hardware */ @@ -563,6 +580,7 @@ static struct dma_async_tx_descriptor * mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, size_t len, unsigned long flags) { + struct mpc_dma *mdma = dma_chan_to_mpc_dma(chan); struct mpc_dma_chan *mchan = dma_chan_to_mpc_dma_chan(chan); struct mpc_dma_desc *mdesc = NULL; struct mpc_dma_tcd *tcd; @@ -577,8 +595,11 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, } spin_unlock_irqrestore(&mchan->lock, iflags); - if (!mdesc) + if (!mdesc) { + /* try to free completed descriptors */ + mpc_dma_process_completed(mdma); return NULL; + } mdesc->error = 0; tcd = mdesc->tcd; @@ -591,7 +612,8 @@ mpc_dma_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, tcd->dsize = MPC_DMA_TSIZE_32; tcd->soff = 32; tcd->doff = 32; - } else if (IS_ALIGNED(src | dst | len, 16)) { + } else if (!mdma->is_mpc8308 && IS_ALIGNED(src | dst | len, 16)) { + /* MPC8308 doesn't support 16 byte transfers */ tcd->ssize = MPC_DMA_TSIZE_16; tcd->dsize = MPC_DMA_TSIZE_16; tcd->soff = 16; @@ -651,6 +673,15 @@ static int __devinit mpc_dma_probe(struct platform_device *op, return -EINVAL; } + if (of_device_is_compatible(dn, "fsl,mpc8308-dma")) { + mdma->is_mpc8308 = 1; + mdma->irq2 = irq_of_parse_and_map(dn, 1); + if (mdma->irq2 == NO_IRQ) { + dev_err(dev, "Error mapping IRQ!\n"); + return -EINVAL; + } + } + retval = of_address_to_resource(dn, 0, &res); if (retval) { dev_err(dev, "Error parsing memory region!\n"); @@ -681,11 +712,23 @@ static int __devinit mpc_dma_probe(struct platform_device *op, return -EINVAL; } + if (mdma->is_mpc8308) { + retval = devm_request_irq(dev, mdma->irq2, &mpc_dma_irq, 0, + DRV_NAME, mdma); + if (retval) { + dev_err(dev, "Error requesting IRQ2!\n"); + return -EINVAL; + } + } + spin_lock_init(&mdma->error_status_lock); dma = &mdma->dma; dma->dev = dev; - dma->chancnt = MPC_DMA_CHANNELS; + if (!mdma->is_mpc8308) + dma->chancnt = MPC_DMA_CHANNELS; + else + dma->chancnt = 16; /* MPC8308 DMA has only 16 channels */ dma->device_alloc_chan_resources = mpc_dma_alloc_chan_resources; dma->device_free_chan_resources = mpc_dma_free_chan_resources; dma->device_issue_pending = mpc_dma_issue_pending; @@ -721,26 +764,40 @@ static int __devinit mpc_dma_probe(struct platform_device *op, * - Round-robin group arbitration, * - Round-robin channel arbitration. */ - out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_EDCG | - MPC_DMA_DMACR_ERGA | MPC_DMA_DMACR_ERCA); - - /* Disable hardware DMA requests */ - out_be32(&mdma->regs->dmaerqh, 0); - out_be32(&mdma->regs->dmaerql, 0); - - /* Disable error interrupts */ - out_be32(&mdma->regs->dmaeeih, 0); - out_be32(&mdma->regs->dmaeeil, 0); - - /* Clear interrupts status */ - out_be32(&mdma->regs->dmainth, 0xFFFFFFFF); - out_be32(&mdma->regs->dmaintl, 0xFFFFFFFF); - out_be32(&mdma->regs->dmaerrh, 0xFFFFFFFF); - out_be32(&mdma->regs->dmaerrl, 0xFFFFFFFF); - - /* Route interrupts to IPIC */ - out_be32(&mdma->regs->dmaihsa, 0); - out_be32(&mdma->regs->dmailsa, 0); + if (!mdma->is_mpc8308) { + out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_EDCG | + MPC_DMA_DMACR_ERGA | MPC_DMA_DMACR_ERCA); + + /* Disable hardware DMA requests */ + out_be32(&mdma->regs->dmaerqh, 0); + out_be32(&mdma->regs->dmaerql, 0); + + /* Disable error interrupts */ + out_be32(&mdma->regs->dmaeeih, 0); + out_be32(&mdma->regs->dmaeeil, 0); + + /* Clear interrupts status */ + out_be32(&mdma->regs->dmainth, 0xFFFFFFFF); + out_be32(&mdma->regs->dmaintl, 0xFFFFFFFF); + out_be32(&mdma->regs->dmaerrh, 0xFFFFFFFF); + out_be32(&mdma->regs->dmaerrl, 0xFFFFFFFF); + + /* Route interrupts to IPIC */ + out_be32(&mdma->regs->dmaihsa, 0); + out_be32(&mdma->regs->dmailsa, 0); + } else { + /* MPC8308 has 16 channels and lacks some registers */ + out_be32(&mdma->regs->dmacr, MPC_DMA_DMACR_ERCA); + + /* enable snooping */ + out_be32(&mdma->regs->dmagpor, MPC_DMA_DMAGPOR_SNOOP_ENABLE); + /* Disable error interrupts */ + out_be32(&mdma->regs->dmaeeil, 0); + + /* Clear interrupts status */ + out_be32(&mdma->regs->dmaintl, 0xFFFF); + out_be32(&mdma->regs->dmaerrl, 0xFFFF); + } /* Register DMA engine */ dev_set_drvdata(dev, mdma); diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index b6e7ddc09d7..4daf9e5a773 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -387,11 +387,10 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, /* Set the DMA ops to the ones from the PCI device, this could be * fishy if we didn't know that on PowerMac it's always direct ops * or iommu ops that will work fine + * + * To get all the fields, copy all archdata */ - dev->ofdev.dev.archdata.dma_ops = - chip->lbus.pdev->dev.archdata.dma_ops; - dev->ofdev.dev.archdata.dma_data = - chip->lbus.pdev->dev.archdata.dma_data; + dev->ofdev.dev.archdata = chip->lbus.pdev->dev.archdata; #endif /* CONFIG_PCI */ #ifdef DEBUG diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 44549272333..2e041fd0a00 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -2213,6 +2213,9 @@ static void fcu_lookup_fans(struct device_node *fcu_node) static int fcu_of_probe(struct platform_device* dev, const struct of_device_id *match) { state = state_detached; + of_dev = dev; + + dev_info(&dev->dev, "PowerMac G5 Thermal control driver %s\n", VERSION); /* Lookup the fans in the device tree */ fcu_lookup_fans(dev->dev.of_node); @@ -2235,6 +2238,7 @@ static const struct of_device_id fcu_match[] = }, {}, }; +MODULE_DEVICE_TABLE(of, fcu_match); static struct of_platform_driver fcu_of_platform_driver = { @@ -2252,8 +2256,6 @@ static struct of_platform_driver fcu_of_platform_driver = */ static int __init therm_pm72_init(void) { - struct device_node *np; - rackmac = of_machine_is_compatible("RackMac3,1"); if (!of_machine_is_compatible("PowerMac7,2") && @@ -2261,34 +2263,12 @@ static int __init therm_pm72_init(void) !rackmac) return -ENODEV; - printk(KERN_INFO "PowerMac G5 Thermal control driver %s\n", VERSION); - - np = of_find_node_by_type(NULL, "fcu"); - if (np == NULL) { - /* Some machines have strangely broken device-tree */ - np = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/fan@15e"); - if (np == NULL) { - printk(KERN_ERR "Can't find FCU in device-tree !\n"); - return -ENODEV; - } - } - of_dev = of_platform_device_create(np, "temperature", NULL); - if (of_dev == NULL) { - printk(KERN_ERR "Can't register FCU platform device !\n"); - return -ENODEV; - } - - of_register_platform_driver(&fcu_of_platform_driver); - - return 0; + return of_register_platform_driver(&fcu_of_platform_driver); } static void __exit therm_pm72_exit(void) { of_unregister_platform_driver(&fcu_of_platform_driver); - - if (of_dev) - of_device_unregister(of_dev); } module_init(therm_pm72_init); diff --git a/drivers/ps3/Makefile b/drivers/ps3/Makefile index ccea15c11c1..50cb1e1b4a1 100644 --- a/drivers/ps3/Makefile +++ b/drivers/ps3/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_PS3_VUART) += ps3-vuart.o obj-$(CONFIG_PS3_PS3AV) += ps3av_mod.o -ps3av_mod-objs += ps3av.o ps3av_cmd.o +ps3av_mod-y := ps3av.o ps3av_cmd.o obj-$(CONFIG_PPC_PS3) += sys-manager-core.o obj-$(CONFIG_PS3_SYS_MANAGER) += ps3-sys-manager.o obj-$(CONFIG_PS3_STORAGE) += ps3stor_lib.o diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 5856167a0c9..7e6ce626b7f 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -687,7 +687,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) #if defined(CONFIG_ATARI) address_space = 64; #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \ - || defined(__sparc__) || defined(__mips__) + || defined(__sparc__) || defined(__mips__) \ + || defined(__powerpc__) address_space = 128; #else #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. |