Re: [PATCH] agp/uninorth: Fix oops caused by flushing too much
On Mit, 2010-06-02 at 15:33 +1000, Paul Mackerras wrote: This fixes a sporadic oops at boot on G5 Power Macs. The table_end variable has the address of the last byte of the table. Adding on PAGE_SIZE means we flush too much, and if the page after the table is not mapped for any reason, the kernel will oops. Instead we add on 1 because flush_dcache_range() interprets its second argument as the first byte past the range to be flushed. Signed-off-by: Paul Mackerras pau...@samba.org Reviewed-by: Michel Dänzer mic...@daenzer.net Tested-by: Michel Dänzer mic...@daenzer.net Thanks for the good catch, Paul. --- diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index 6f48931..9aaa0eb 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -413,7 +413,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) bridge-gatt_table_real = (u32 *) table; /* Need to clear out any dirty data still sitting in caches */ flush_dcache_range((unsigned long)table, -(unsigned long)(table_end + PAGE_SIZE)); +(unsigned long)table_end + 1); bridge-gatt_table = vmap(pages, (1 page_order), 0, PAGE_KERNEL_NCG); if (bridge-gatt_table == NULL) -- Earthling Michel Dänzer |http://www.vmware.com Libre software enthusiast | Debian, X and DRI developer ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC][PATCH] irq: support IRQ_NESTED_THREAD with non-threaded interrupt handlers
On Mon, 7 Jun 2010, Esben Haabendal wrote: On Mon, Jun 7, 2010 at 5:06 PM, Thomas Gleixner t...@linutronix.de wrote: Maybe you understand now, why I was pretty sure upfront, that your approach was wrong even without knowing all the gory details ? :) I understand. There is a better solution, which is to use threaded interrupts where needed. FWIW, it just occured to me, that the only reason why the disable_irq_nosysnc() trips up on the in_atomic() check is your fiddling with the nested irq dispatcher. If you just would have changed the phy driver to request_irq_any_context() it would have simply worked out of the box, without any need to remove buslock and changing genirq code at all. That would not give you the advantage of getting rid of the two additional I2C transfers, but that's nn optimzation not a functional requirement. Thanks, tglx ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Packet error when using kgdb
Hi all: I want to use kgdb debug kernel and driver on 8641d_hpcn. I refer to Essential linux device drivers. I compile the kernel, open Magic SysRq key and kgdb option in menuconfig. But, when I use ttyS0 connect to target board. I meet the error: Ignoring packet error, continuing... Ignoring packet error, continuing... Ignoring packet error, continuing... Malformed response to offset query, timeout Sometimes, I can connect to target board.But when I set breakpoint and step to debug. I meet the same error above. I use kernel v2.6.27.38.Toolchain is ELDK for ppc. Is the kgdb tool not stable? I am a freeshman. Hope getting some suggestiong. Thank you! ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC][PATCH] irq: support IRQ_NESTED_THREAD with non-threaded interrupt handlers
On Tue, 2010-06-08 at 08:58 +0200, Thomas Gleixner wrote: On Mon, 7 Jun 2010, Esben Haabendal wrote: On Mon, Jun 7, 2010 at 5:06 PM, Thomas Gleixner t...@linutronix.de wrote: Maybe you understand now, why I was pretty sure upfront, that your approach was wrong even without knowing all the gory details ? :) I understand. There is a better solution, which is to use threaded interrupts where needed. FWIW, it just occured to me, that the only reason why the disable_irq_nosysnc() trips up on the in_atomic() check is your fiddling with the nested irq dispatcher. If you just would have changed the phy driver to request_irq_any_context() it would have simply worked out of the box, without any need to remove buslock and changing genirq code at all. That would not give you the advantage of getting rid of the two additional I2C transfers, but that's nn optimzation not a functional requirement. Now, that is good news. Thanks! /Esben ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] kexec, ppc64: Wait for online/possible CPUs only.
kexec_perpare_cpus_wait() iterates i through NR_CPUS to check paca[i].kexec_state of each to make sure they have quiesced. However now we have dynamic PACA allocation, paca[NR_CPUS] is not necessarily valid and we overrun the array; spurious cpu is not possible, ignoring errors result. This patch iterates for_each_online_cpu so stays within the bounds of paca[] -- and every CPU is now 'possible'. Signed-off-by: Matt Evans m...@ozlabs.org --- arch/powerpc/kernel/machine_kexec_64.c | 18 +- 1 files changed, 1 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index 26f9900..ed31a29 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c @@ -182,28 +182,12 @@ static void kexec_prepare_cpus_wait(int wait_state) my_cpu = get_cpu(); /* Make sure each CPU has atleast made it to the state we need */ - for (i=0; i NR_CPUS; i++) { + for_each_online_cpu(i) { if (i == my_cpu) continue; while (paca[i].kexec_state wait_state) { barrier(); - if (!cpu_possible(i)) { - printk(kexec: cpu %d hw_cpu_id %d is not -possible, ignoring\n, - i, paca[i].hw_cpu_id); - break; - } - if (!cpu_online(i)) { - /* Fixme: this can be spinning in -* pSeries_secondary_wait with a paca -* waiting for it to go online. -*/ - printk(kexec: cpu %d hw_cpu_id %d is not -online, ignoring\n, - i, paca[i].hw_cpu_id); - break; - } if (i != notified) { printk( kexec: waiting for cpu %d (physical %d) to enter %i state\n, -- 1.6.3.3 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc: Fix integer constant warning
Steve Best sfb...@us.ibm.com wrote: -#define KERNELBASE (0xc000) +#define KERNELBASE (0xc000ULL) Is this the right fix? The code producing the warning is subtracting 0xc000 from a 32-bit number: naca = ntohl(*((u_int32_t*) inbuf[0x0C])) - KERNELBASE; which seems distinctly odd. David ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc: Fix integer constant warning
On Tue, Jun 08, 2010 at 02:12:26PM +0100, David Howells wrote: Steve Best sfb...@us.ibm.com wrote: -#define KERNELBASE (0xc000) +#define KERNELBASE (0xc000ULL) Is this the right fix? The code producing the warning is subtracting 0xc000 from a 32-bit number: It might not matter, since Paul sent a patch to remove this file entirely. josh ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/5] of/address: merge of_iomap()
Merge common code between Microblaze and PowerPC. This patch creates new of_address.h and address.c files to containing address translation and mapping routines. First routine to be moved it of_iomap() Signed-off-by: Grant Likely grant.lik...@secretlab.ca CC: Michal Simek mon...@monstr.eu CC: Wolfram Sang w.s...@pengutronix.de CC: Stephen Rothwell s...@canb.auug.org.au CC: Benjamin Herrenschmidt b...@kernel.crashing.org CC: microblaze-ucli...@itee.uq.edu.au CC: linuxppc-...@ozlabs.org --- arch/microblaze/include/asm/prom.h | 10 +- arch/microblaze/kernel/prom_parse.c | 11 --- arch/powerpc/include/asm/prom.h | 10 +- arch/powerpc/kernel/prom_parse.c| 11 --- drivers/of/Kconfig |4 drivers/of/Makefile |1 + drivers/of/address.c| 22 ++ include/linux/of_address.h |9 + 8 files changed, 38 insertions(+), 40 deletions(-) create mode 100644 drivers/of/address.c create mode 100644 include/linux/of_address.h diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 3659930..b6698ef 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -20,6 +20,7 @@ #ifndef __ASSEMBLY__ #include linux/types.h +#include linux/of_address.h #include linux/of_irq.h #include linux/of_fdt.h #include linux/proc_fs.h @@ -107,15 +108,6 @@ extern const void *of_get_mac_address(struct device_node *np); struct pci_dev; extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); -/** - * of_iomap - Maps the memory mapped IO for a given device_node - * @device:the device whose io range will be mapped - * @index: index of the io range - * - * Returns a pointer to the mapped memory - */ -extern void __iomem *of_iomap(struct device_node *device, int index); - #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_MICROBLAZE_PROM_H */ diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c index 70c0471..5003ee8 100644 --- a/arch/microblaze/kernel/prom_parse.c +++ b/arch/microblaze/kernel/prom_parse.c @@ -697,14 +697,3 @@ const void *of_get_mac_address(struct device_node *np) return NULL; } EXPORT_SYMBOL(of_get_mac_address); - -void __iomem *of_iomap(struct device_node *np, int index) -{ - struct resource res; - - if (of_address_to_resource(np, index, res)) - return NULL; - - return ioremap(res.start, 1 + res.end - res.start); -} -EXPORT_SYMBOL(of_iomap); diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 2440984..e0bdbc6 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -18,6 +18,7 @@ */ #include linux/types.h #include linux/of_fdt.h +#include linux/of_address.h #include linux/of_irq.h #include linux/proc_fs.h #include linux/platform_device.h @@ -136,14 +137,5 @@ extern void of_irq_map_init(unsigned int flags); struct pci_dev; extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); -/** - * of_iomap - Maps the memory mapped IO for a given device_node - * @device:the device whose io range will be mapped - * @index: index of the io range - * - * Returns a pointer to the mapped memory - */ -extern void __iomem *of_iomap(struct device_node *device, int index); - #endif /* __KERNEL__ */ #endif /* _POWERPC_PROM_H */ diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index ef518e3..dfb73c4 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -822,14 +822,3 @@ const void *of_get_mac_address(struct device_node *np) return NULL; } EXPORT_SYMBOL(of_get_mac_address); - -void __iomem *of_iomap(struct device_node *np, int index) -{ - struct resource res; - - if (of_address_to_resource(np, index, res)) - return NULL; - - return ioremap(res.start, 1 + res.end - res.start); -} -EXPORT_SYMBOL(of_iomap); diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index b87495e..097f42a 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -6,6 +6,10 @@ config OF_DYNAMIC def_bool y depends on OF PPC_OF +config OF_ADDRESS + def_bool y + depends on OF !SPARC + config OF_IRQ def_bool y depends on OF !SPARC diff --git a/drivers/of/Makefile b/drivers/of/Makefile index 3631a5e..0052c40 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -1,5 +1,6 @@ obj-y = base.o obj-$(CONFIG_OF_FLATTREE) += fdt.o +obj-$(CONFIG_OF_ADDRESS) += address.o obj-$(CONFIG_OF_IRQ)+= irq.o obj-$(CONFIG_OF_DEVICE) += device.o platform.o obj-$(CONFIG_OF_GPIO) += gpio.o diff --git a/drivers/of/address.c b/drivers/of/address.c new file mode 100644 index 000..258528d --- /dev/null +++ b/drivers/of/address.c @@ -0,0 +1,22 @@ + +#include linux/io.h +#include
[PATCH 2/5] of/address: merge of_address_to_resource()
Merge common code between PowerPC and Microblaze. This patch also moves the prototype of pci_address_to_pio() out of pci-bridge.h and into prom.h because the only user of pci_address_to_pio() is of_address_to_resource(). Signed-off-by: Grant Likely grant.lik...@secretlab.ca CC: Michal Simek mon...@monstr.eu CC: Grant Likely grant.lik...@secretlab.ca CC: Wolfram Sang w.s...@pengutronix.de CC: Stephen Rothwell s...@canb.auug.org.au CC: Benjamin Herrenschmidt b...@kernel.crashing.org CC: microblaze-ucli...@itee.uq.edu.au CC: linuxppc-...@ozlabs.org --- arch/microblaze/include/asm/pci-bridge.h |5 --- arch/microblaze/include/asm/prom.h | 17 +- arch/microblaze/kernel/prom_parse.c | 46 +-- arch/powerpc/include/asm/pci-bridge.h|5 --- arch/powerpc/include/asm/prom.h | 17 +- arch/powerpc/kernel/prom_parse.c | 47 +--- drivers/of/address.c | 51 ++ include/linux/of_address.h |5 +++ 8 files changed, 76 insertions(+), 117 deletions(-) diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h index 0c77cda..0c68764 100644 --- a/arch/microblaze/include/asm/pci-bridge.h +++ b/arch/microblaze/include/asm/pci-bridge.h @@ -172,13 +172,8 @@ static inline int pci_has_flag(int flag) extern struct list_head hose_list; -extern unsigned long pci_address_to_pio(phys_addr_t address); extern int pcibios_vaddr_is_ioport(void __iomem *address); #else -static inline unsigned long pci_address_to_pio(phys_addr_t address) -{ - return (unsigned long)-1; -} static inline int pcibios_vaddr_is_ioport(void __iomem *address) { return 0; diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index b6698ef..644fa32 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -65,17 +65,18 @@ extern const u32 *of_get_address(struct device_node *dev, int index, extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, unsigned int *flags); -/* Get an address as a resource. Note that if your address is - * a PIO address, the conversion will fail if the physical address - * can't be internally converted to an IO token with - * pci_address_to_pio(), that is because it's either called to early - * or it can't be matched to any host bridge IO space - */ -extern int of_address_to_resource(struct device_node *dev, int index, - struct resource *r); extern int of_pci_address_to_resource(struct device_node *dev, int bar, struct resource *r); +#ifdef CONFIG_PCI +extern unsigned long pci_address_to_pio(phys_addr_t address); +#else +static inline unsigned long pci_address_to_pio(phys_addr_t address) +{ + return (unsigned long)-1; +} +#endif /* CONFIG_PCI */ + /* Parse the ibm,dma-window property of an OF node into the busno, phys and * size parameters. */ diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c index 5003ee8..7cb5a98 100644 --- a/arch/microblaze/kernel/prom_parse.c +++ b/arch/microblaze/kernel/prom_parse.c @@ -6,6 +6,7 @@ #include linux/module.h #include linux/ioport.h #include linux/etherdevice.h +#include linux/of_address.h #include asm/prom.h #include asm/pci-bridge.h @@ -17,9 +18,6 @@ (ns) 0) static struct of_bus *of_match_bus(struct device_node *np); -static int __of_address_to_resource(struct device_node *dev, - const u32 *addrp, u64 size, unsigned int flags, - struct resource *r); /* Debug utility */ #ifdef DEBUG @@ -576,48 +574,6 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size, } EXPORT_SYMBOL(of_get_address); -static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, - u64 size, unsigned int flags, - struct resource *r) -{ - u64 taddr; - - if ((flags (IORESOURCE_IO | IORESOURCE_MEM)) == 0) - return -EINVAL; - taddr = of_translate_address(dev, addrp); - if (taddr == OF_BAD_ADDR) - return -EINVAL; - memset(r, 0, sizeof(struct resource)); - if (flags IORESOURCE_IO) { - unsigned long port; - port = -1; /* pci_address_to_pio(taddr); */ - if (port == (unsigned long)-1) - return -EINVAL; - r-start = port; - r-end = port + size - 1; - } else { - r-start = taddr; - r-end = taddr + size - 1; - } - r-flags = flags; - r-name = dev-name; - return 0; -} - -int of_address_to_resource(struct device_node *dev, int index, - struct resource *r) -{ - const u32
[PATCH 5/5] of/address: restrict 'no-ranges' kludge to powerpc
Certain Apple machines don't use the ranges property correctly, but the workaround should not be applied on other architectures. This patch disables the workaround for non-powerpc architectures. Signed-off-by: Grant Likely grant.lik...@secretlab.ca CC: Stephen Rothwell s...@canb.auug.org.au CC: Benjamin Herrenschmidt b...@kernel.crashing.org CC: linuxppc-dev@lists.ozlabs.org CC: devicetree-disc...@lists.ozlabs.org --- drivers/of/address.c | 11 ++- 1 files changed, 10 insertions(+), 1 deletions(-) diff --git a/drivers/of/address.c b/drivers/of/address.c index 0b04137..5c220c3 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -346,12 +346,21 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, * a 1:1 translation at that level. It's up to the caller not to try * to translate addresses that aren't supposed to be translated in * the first place. --BenH. +* +* As far as we know, this damage only exists on Apple machines, so +* This code is only enabled on powerpc. --gcl */ ranges = of_get_property(parent, rprop, rlen); +#if !defined(CONFIG_PPC) + if (ranges == NULL) { + pr_err(OF: no ranges; cannot translate\n); + return 1; + } +#endif /* !defined(CONFIG_PPC) */ if (ranges == NULL || rlen == 0) { offset = of_read_number(addr, na); memset(addr, 0, pna * 4); - pr_debug(OF: no ranges, 1:1 translation\n); + pr_debug(OF: empty ranges; 1:1 translation\n); goto finish; } ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 0/5] Merge common address translation code (ppc mb)
These five patches merge common code for decoding address ranges from the device tree. Simple mechanical change. There should be no functional difference except for the last patch which restricts the no-ranges code to be powerpc-only. These patches are based on top of the IRQ merge which I posted earlier. If you want to test them, I've pushed the commits out to the here: git://git.secretlab.ca/git/linux-2.6 devicetree-test Cheers, g. --- Grant Likely (5): of/address: merge of_iomap() of/address: merge of_address_to_resource() of/address: Merge all of the bus translation code of/address: little-endian fixes of/address: restrict 'no-ranges' kludge to powerpc arch/microblaze/include/asm/pci-bridge.h | 5 arch/microblaze/include/asm/prom.h | 31 +- arch/microblaze/kernel/prom_parse.c | 546 arch/powerpc/include/asm/pci-bridge.h | 5 arch/powerpc/include/asm/prom.h | 31 +- arch/powerpc/kernel/prom_parse.c | 573 - drivers/of/Kconfig | 4 drivers/of/Makefile | 1 drivers/of/address.c | 595 ++ include/linux/of_address.h | 12 + 10 files changed, 634 insertions(+), 1169 deletions(-) create mode 100644 drivers/of/address.c create mode 100644 include/linux/of_address.h -- Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 4/5] of/address: little-endian fixes
Fix some endian issues in the OF address translation code. Signed-off-by: Grant Likely grant.lik...@secretlab.ca CC: Michal Simek mon...@monstr.eu CC: Wolfram Sang w.s...@pengutronix.de CC: Stephen Rothwell s...@canb.auug.org.au CC: Benjamin Herrenschmidt b...@kernel.crashing.org CC: microblaze-ucli...@itee.uq.edu.au CC: linuxppc-...@ozlabs.org --- drivers/of/address.c | 12 +++- 1 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/of/address.c b/drivers/of/address.c index 2a905d5..0b04137 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -22,7 +22,7 @@ static void of_dump_addr(const char *s, const u32 *addr, int na) { printk(KERN_DEBUG %s, s); while (na--) - printk( %08x, *(addr++)); + printk( %08x, be32_to_cpu(*(addr++))); printk(\n); } #else @@ -79,8 +79,8 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na) memset(addr, 0, na * 4); a += offset; if (na 1) - addr[na - 2] = a 32; - addr[na - 1] = a 0xu; + addr[na - 2] = cpu_to_be32(a 32); + addr[na - 1] = cpu_to_be32(a 0xu); return 0; } @@ -190,14 +190,16 @@ const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, psize /= 4; onesize = na + ns; - for (i = 0; psize = onesize; psize -= onesize, prop += onesize, i++) - if ((prop[0] 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { + for (i = 0; psize = onesize; psize -= onesize, prop += onesize, i++) { + u32 val = be32_to_cpu(prop[0]); + if ((val 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { if (size) *size = of_read_number(prop + na, ns); if (flags) *flags = bus-get_flags(prop); return prop; } + } return NULL; } EXPORT_SYMBOL(of_get_pci_address); ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC][PATCH] irq: support IRQ_NESTED_THREAD with non-threaded interrupt handlers
On Tue, 2010-06-08 at 01:18 +0200, Thomas Gleixner wrote: On Mon, 7 Jun 2010, Esben Haabendal wrote: On Mon, Jun 7, 2010 at 5:06 PM, Thomas Gleixner t...@linutronix.de wrote: Maybe you understand now, why I was pretty sure upfront, that your approach was wrong even without knowing all the gory details ? :) I understand. There is a better solution, which is to use threaded interrupts where needed. But I must confess that I am disappointed that you still fail to see how the pca953x patch actually eliminates the need for serialization. But I don't think there is much point in going on about that. I return the favour of being disappointed that you are still failing to accept that there is a fundamental difference between it works in a particular case and semantical correctness under all circumstances. No reason to do that. I must have misunderstood you then. I understand that the general case, I just never got the point where you understood what I did that (I believe) makes it actually work (not just for now, but really work), in my particular case. There is no place for it works in a particular case in a kernel which runs on a gazillion of different devices unless you want to create a complete unmaintainable mess. The only way to avoid this is to be strict about semantics even if it seems unsensible for a particular case. I won't argue against. Not at all. Also I explained it to you in great length, that your patch violates the semantical guarantees of existing functions, but you ignore that completely. And I answered you several times, that I understand your point, but It's Open Source, go wild and change it for your particular case - but don't expect that I accept patches to the generic irq code which will cause _me_ predictable trouble as I have to deal with the fallout. Neither expect, that I ack patches to users of that code which are semantically wrong. Just for the record, the pca953x driver is broken vs. the local state protection anyway as the GPIO functions are not serialized against the interrupt controller functions. There is no magic which prevents that, neither on your system nor on any other. The GPIO function should take buslock when modifying local state and that's one of the reasons why buslock it is there and cannot go away. Ok, so the genirq buslock should be held in fx. pca953x_gpio_direction_input and pca953x_gpio_direction_output ? That makes sense in combination with the currently implemented bus_sync_unlock. But I still fail to see why it is needed, or even desired, that the setting of direction should be related to the genirq code at all. I see it as a sane seperation to let the actual gpio code handle the direction setting, and the irq code to handle the (in software) irq mask. Driver and/or board code should be sane enough to set pca953x gpio's as input if/when interrupts from them are needed. And they should do this in advance. And by doing it this way, there should not be any hardware state to serialize, and there actually is no pca953x driver local state either, as the pca953x_chip members are either exclusively managed by gpio or irq code. I'm anticipating that you are going to tell me that it does not matter on your particular powerpc combined with your usage pattern (i.e no GPIO users). And I tell you right away, that I'm not interested in this answer for well explained reasons. No, I don't tie it to my particular usage pattern. I tell you that I don't need it (serialization) on powerpc because my pca953x powerpc patch have removed the need for shared local state between gpio and irq code. Of-course, for the pca953x driver to be acceptable, it would be nice (or more likely, required) to unify it for other archs also, I just don't see how to do that. That said, I will proceed with the request_any_context_irq() in the phy driver instead :-) Case closed for now. /Esben ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc: Fix integer constant warning
Josh Boyer jwbo...@linux.vnet.ibm.com wrote: It might not matter, since Paul sent a patch to remove this file entirely. Yeah, I saw that after... David ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/6] of: Use full node name in resource structures
Resource names appear in human readable output, so when extracting IRQ and address resources from a device tree node, use the full node name to give proper context in places like /proc/iomem. Signed-off-by: Grant Likely grant.lik...@secretlab.ca CC: Michal Simek mon...@monstr.eu CC: Stephen Rothwell s...@canb.auug.org.au CC: Benjamin Herrenschmidt b...@kernel.crashing.org CC: microblaze-ucli...@itee.uq.edu.au CC: linuxppc-...@ozlabs.org --- drivers/of/address.c |2 +- drivers/of/irq.c |1 + 2 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/of/address.c b/drivers/of/address.c index 5c220c3..fcadb72 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -549,7 +549,7 @@ static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, r-end = taddr + size - 1; } r-flags = flags; - r-name = dev-name; + r-name = dev-full_name; return 0; } diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 5c097be..8e8cdce 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -330,6 +330,7 @@ unsigned int of_irq_to_resource(struct device_node *dev, int index, if (r irq != NO_IRQ) { r-start = r-end = irq; r-flags = IORESOURCE_IRQ; + r-name = dev-full_name; } return irq; ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/6] of/device: merge of_device_uevent
Merge common code between powerpc and microblaze Signed-off-by: Grant Likely grant.lik...@secretlab.ca CC: Michal Simek mon...@monstr.eu CC: Wolfram Sang w.s...@pengutronix.de CC: Stephen Rothwell s...@canb.auug.org.au CC: Benjamin Herrenschmidt b...@kernel.crashing.org CC: microblaze-ucli...@itee.uq.edu.au CC: linuxppc-...@ozlabs.org --- arch/microblaze/include/asm/of_device.h |3 -- arch/microblaze/kernel/of_device.c | 48 -- arch/powerpc/include/asm/of_device.h|3 -- arch/powerpc/kernel/of_device.c | 49 --- drivers/of/device.c | 48 ++ include/linux/of_device.h |4 +++ 6 files changed, 52 insertions(+), 103 deletions(-) diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h index 0a5f3f9..58e627d 100644 --- a/arch/microblaze/include/asm/of_device.h +++ b/arch/microblaze/include/asm/of_device.h @@ -22,9 +22,6 @@ extern struct of_device *of_device_alloc(struct device_node *np, const char *bus_id, struct device *parent); -extern int of_device_uevent(struct device *dev, - struct kobj_uevent_env *env); - extern void of_device_make_bus_id(struct of_device *dev); /* This is just here during the transition */ diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c index b372787..3a367d7 100644 --- a/arch/microblaze/kernel/of_device.c +++ b/arch/microblaze/kernel/of_device.c @@ -62,51 +62,3 @@ struct of_device *of_device_alloc(struct device_node *np, return dev; } EXPORT_SYMBOL(of_device_alloc); - -int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct of_device *ofdev; - const char *compat; - int seen = 0, cplen, sl; - - if (!dev) - return -ENODEV; - - ofdev = to_of_device(dev); - - if (add_uevent_var(env, OF_NAME=%s, ofdev-dev.of_node-name)) - return -ENOMEM; - - if (add_uevent_var(env, OF_TYPE=%s, ofdev-dev.of_node-type)) - return -ENOMEM; - - /* Since the compatible field can contain pretty much anything -* it's not really legal to split it out with commas. We split it -* up using a number of environment variables instead. */ - - compat = of_get_property(ofdev-dev.of_node, compatible, cplen); - while (compat *compat cplen 0) { - if (add_uevent_var(env, OF_COMPATIBLE_%d=%s, seen, compat)) - return -ENOMEM; - - sl = strlen(compat) + 1; - compat += sl; - cplen -= sl; - seen++; - } - - if (add_uevent_var(env, OF_COMPATIBLE_N=%d, seen)) - return -ENOMEM; - - /* modalias is trickier, we add it in 2 steps */ - if (add_uevent_var(env, MODALIAS=)) - return -ENOMEM; - sl = of_device_get_modalias(ofdev, env-buf[env-buflen-1], - sizeof(env-buf) - env-buflen); - if (sl = (sizeof(env-buf) - env-buflen)) - return -ENOMEM; - env-buflen += sl; - - return 0; -} -EXPORT_SYMBOL(of_device_uevent); diff --git a/arch/powerpc/include/asm/of_device.h b/arch/powerpc/include/asm/of_device.h index cb36632..5d5103c 100644 --- a/arch/powerpc/include/asm/of_device.h +++ b/arch/powerpc/include/asm/of_device.h @@ -9,8 +9,5 @@ extern struct of_device *of_device_alloc(struct device_node *np, const char *bus_id, struct device *parent); -extern int of_device_uevent(struct device *dev, - struct kobj_uevent_env *env); - #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_OF_DEVICE_H */ diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index df78e02..db91a9d 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -82,52 +82,3 @@ struct of_device *of_device_alloc(struct device_node *np, return dev; } EXPORT_SYMBOL(of_device_alloc); - -int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct of_device *ofdev; - const char *compat; - int seen = 0, cplen, sl; - - if (!dev) - return -ENODEV; - - ofdev = to_of_device(dev); - - if (add_uevent_var(env, OF_NAME=%s, ofdev-dev.of_node-name)) - return -ENOMEM; - - if (add_uevent_var(env, OF_TYPE=%s, ofdev-dev.of_node-type)) - return -ENOMEM; - -/* Since the compatible field can contain pretty much anything - * it's not really legal to split it out with commas. We split it - * up using a number of environment variables instead. */ - - compat = of_get_property(ofdev-dev.of_node, compatible,
[PATCH 3/6] of: Modify of_device_get_modalias to be passed struct device
Now that the of_node pointer is part of struct device, of_device_get_modalias could be used on any struct device that has the device node pointer set. This patch changes of_device_get_modalias to accept a struct device instead of a struct of_device. Signed-off-by: Grant Likely grant.lik...@secretlab.ca CC: Michal Simek mon...@monstr.eu CC: Benjamin Herrenschmidt b...@kernel.crashing.org CC: Wolfram Sang w.s...@pengutronix.de CC: Stephen Rothwell s...@canb.auug.org.au CC: microblaze-ucli...@itee.uq.edu.au CC: linuxppc-...@ozlabs.org --- arch/microblaze/include/asm/of_device.h |3 --- drivers/macintosh/macio_sysfs.c |5 + drivers/of/device.c | 16 ++-- include/linux/of_device.h |2 +- 4 files changed, 8 insertions(+), 18 deletions(-) diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h index 58e627d..c9be534 100644 --- a/arch/microblaze/include/asm/of_device.h +++ b/arch/microblaze/include/asm/of_device.h @@ -15,9 +15,6 @@ #include linux/device.h #include linux/of.h -extern ssize_t of_device_get_modalias(struct of_device *ofdev, - char *str, ssize_t len); - extern struct of_device *of_device_alloc(struct device_node *np, const char *bus_id, struct device *parent); diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c index 6999ce5..6024038 100644 --- a/drivers/macintosh/macio_sysfs.c +++ b/drivers/macintosh/macio_sysfs.c @@ -41,10 +41,7 @@ compatible_show (struct device *dev, struct device_attribute *attr, char *buf) static ssize_t modalias_show (struct device *dev, struct device_attribute *attr, char *buf) { - struct of_device *ofdev = to_of_device(dev); - int len; - - len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2); + int len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2); buf[len] = '\n'; buf[len+1] = 0; diff --git a/drivers/of/device.c b/drivers/of/device.c index 275cc9c..c2a98f5 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -68,10 +68,7 @@ static ssize_t name_show(struct device *dev, static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct of_device *ofdev = to_of_device(dev); - ssize_t len = 0; - - len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2); + ssize_t len = of_device_get_modalias(dev, buf, PAGE_SIZE - 2); buf[len] = '\n'; buf[len+1] = 0; return len+1; @@ -123,19 +120,18 @@ void of_device_unregister(struct of_device *ofdev) } EXPORT_SYMBOL(of_device_unregister); -ssize_t of_device_get_modalias(struct of_device *ofdev, - char *str, ssize_t len) +ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) { const char *compat; int cplen, i; ssize_t tsize, csize, repend; /* Name Type */ - csize = snprintf(str, len, of:N%sT%s, ofdev-dev.of_node-name, -ofdev-dev.of_node-type); + csize = snprintf(str, len, of:N%sT%s, dev-of_node-name, +dev-of_node-type); /* Get compatible property if any */ - compat = of_get_property(ofdev-dev.of_node, compatible, cplen); + compat = of_get_property(dev-of_node, compatible, cplen); if (!compat) return csize; @@ -210,7 +206,7 @@ int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) if (add_uevent_var(env, MODALIAS=)) return -ENOMEM; - sl = of_device_get_modalias(to_of_device(dev), env-buf[env-buflen-1], + sl = of_device_get_modalias(dev, env-buf[env-buflen-1], sizeof(env-buf) - env-buflen); if (sl = (sizeof(env-buf) - env-buflen)) return -ENOMEM; diff --git a/include/linux/of_device.h b/include/linux/of_device.h index da83e73..238e92e 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -42,7 +42,7 @@ static inline void of_device_free(struct of_device *dev) of_release_dev(dev-dev); } -extern ssize_t of_device_get_modalias(struct of_device *ofdev, +extern ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len); extern int of_device_uevent(struct device *dev, struct kobj_uevent_env *env); ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 5/6] of: Merge of_device_alloc
Merge common code between PowerPC and Microblaze Signed-off-by: Grant Likely grant.lik...@secretlab.ca CC: Michal Simek mon...@monstr.eu CC: Grant Likely grant.lik...@secretlab.ca CC: Benjamin Herrenschmidt b...@kernel.crashing.org CC: Stephen Rothwell s...@canb.auug.org.au CC: microblaze-ucli...@itee.uq.edu.au CC: linuxppc-...@ozlabs.org CC: devicetree-disc...@lists.ozlabs.org --- arch/microblaze/include/asm/device.h|3 + arch/microblaze/include/asm/of_device.h | 15 --- arch/microblaze/kernel/Makefile |2 - arch/microblaze/kernel/of_device.c | 64 --- arch/powerpc/include/asm/device.h |3 + arch/powerpc/include/asm/of_device.h| 10 - arch/powerpc/kernel/of_device.c | 61 -- drivers/of/platform.c | 53 ++ include/linux/of_platform.h |4 ++ 9 files changed, 72 insertions(+), 143 deletions(-) delete mode 100644 arch/microblaze/kernel/of_device.c diff --git a/arch/microblaze/include/asm/device.h b/arch/microblaze/include/asm/device.h index 123b2fe..5e63552 100644 --- a/arch/microblaze/include/asm/device.h +++ b/arch/microblaze/include/asm/device.h @@ -21,6 +21,9 @@ struct pdev_archdata { u64 dma_mask; }; +/* Don't override the default bus id behaviour */ +#define of_device_make_bus_id __of_device_make_bus_id + #endif /* _ASM_MICROBLAZE_DEVICE_H */ diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h index c9be534..47e8d42 100644 --- a/arch/microblaze/include/asm/of_device.h +++ b/arch/microblaze/include/asm/of_device.h @@ -10,19 +10,4 @@ #ifndef _ASM_MICROBLAZE_OF_DEVICE_H #define _ASM_MICROBLAZE_OF_DEVICE_H -#ifdef __KERNEL__ - -#include linux/device.h -#include linux/of.h - -extern struct of_device *of_device_alloc(struct device_node *np, -const char *bus_id, -struct device *parent); - -extern void of_device_make_bus_id(struct of_device *dev); - -/* This is just here during the transition */ -#include linux/of_device.h - -#endif /* __KERNEL__ */ #endif /* _ASM_MICROBLAZE_OF_DEVICE_H */ diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index e51bc15..727e2cb 100644 --- a/arch/microblaze/kernel/Makefile +++ b/arch/microblaze/kernel/Makefile @@ -15,7 +15,7 @@ endif extra-y := head.o vmlinux.lds obj-y += dma.o exceptions.o \ - hw_exception_handler.o init_task.o intc.o irq.o of_device.o \ + hw_exception_handler.o init_task.o intc.o irq.o \ of_platform.o process.o prom.o prom_parse.o ptrace.o \ setup.o signal.o sys_microblaze.o timer.o traps.o reset.o diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c deleted file mode 100644 index 3a367d7..000 --- a/arch/microblaze/kernel/of_device.c +++ /dev/null @@ -1,64 +0,0 @@ -#include linux/string.h -#include linux/kernel.h -#include linux/of.h -#include linux/init.h -#include linux/module.h -#include linux/mod_devicetable.h -#include linux/slab.h -#include linux/of_device.h - -#include linux/errno.h - -void of_device_make_bus_id(struct of_device *dev) -{ - static atomic_t bus_no_reg_magic; - struct device_node *node = dev-dev.of_node; - const u32 *reg; - u64 addr; - int magic; - - /* -* For MMIO, get the physical address -*/ - reg = of_get_property(node, reg, NULL); - if (reg) { - addr = of_translate_address(node, reg); - if (addr != OF_BAD_ADDR) { - dev_set_name(dev-dev, %llx.%s, -(unsigned long long)addr, node-name); - return; - } - } - - /* -* No BusID, use the node name and add a globally incremented -* counter (and pray...) -*/ - magic = atomic_add_return(1, bus_no_reg_magic); - dev_set_name(dev-dev, %s.%d, node-name, magic - 1); -} -EXPORT_SYMBOL(of_device_make_bus_id); - -struct of_device *of_device_alloc(struct device_node *np, - const char *bus_id, - struct device *parent) -{ - struct of_device *dev; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return NULL; - - dev-dev.of_node = of_node_get(np); - dev-dev.dma_mask = dev-archdata.dma_mask; - dev-dev.parent = parent; - dev-dev.release = of_release_dev; - - if (bus_id) - dev_set_name(dev-dev, bus_id); - else - of_device_make_bus_id(dev); - - return dev; -} -EXPORT_SYMBOL(of_device_alloc); diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index a3954e4..3c897a8 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@
[PATCH 6/6] of/device: populate platform_device (of_device) resource table on allocation
When allocating a platform_device to represent an OF node, also allocate space for the resource table and populate it with IRQ and reg property information. This change is in preparation for merging the of_platform_bus_type with the platform_bus_type so that existing platform_driver code can retrieve base addresses and IRQs data. Background: a previous commit removed struct of_device and made it a #define alias for platform_device. Signed-off-by: Grant Likely grant.lik...@secretlab.ca CC: Michal Simek mon...@monstr.eu CC: Grant Likely grant.lik...@secretlab.ca CC: Benjamin Herrenschmidt b...@kernel.crashing.org CC: Stephen Rothwell s...@canb.auug.org.au CC: microblaze-ucli...@itee.uq.edu.au CC: linuxppc-...@ozlabs.org CC: devicetree-disc...@lists.ozlabs.org --- drivers/of/platform.c | 31 --- 1 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 4bb898d..10ad0b6 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -441,16 +441,41 @@ struct of_device *of_device_alloc(struct device_node *np, struct device *parent) { struct of_device *dev; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + int rc, i, num_reg = 0, num_irq = 0; + struct resource *res, temp_res; + + /* First count how many resources are needed */ + while (of_address_to_resource(np, num_reg, temp_res) == 0) + num_reg++; + while (of_irq_to_resource(np, num_irq, temp_res) != NO_IRQ) + num_irq++; + + /* Allocate the device including space for the resource table, and +* initialize it. */ + i = num_reg + num_irq; + dev = kzalloc(sizeof(*dev) + (sizeof(struct resource) * i), GFP_KERNEL); if (!dev) return NULL; - dev-dev.of_node = of_node_get(np); dev-dev.dma_mask = dev-archdata.dma_mask; dev-dev.parent = parent; dev-dev.release = of_release_dev; + /* Populate the resource table */ + if (num_irq || num_reg) { + dev-resource = (void*)dev[1]; + dev-num_resources = num_reg + num_irq; + res = dev-resource; + for (i = 0; i num_reg; i++, res++) { + rc = of_address_to_resource(np, i, res); + WARN_ON(rc); + } + for (i = 0; i num_irq; i++, res++) { + rc = of_irq_to_resource(np, i, res); + WARN_ON(rc == NO_IRQ); + } + } + if (bus_id) dev_set_name(dev-dev, %s, bus_id); else ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 4/6] of/device: Merge of_platform_bus_probe()
Merge common code between PowerPC and microblaze. This patch merges the code that scans the tree and registers devices. The functions merged are of_platform_bus_probe(), of_platform_bus_create(), and of_platform_device_create(). This patch also move the of_default_bus_ids[] table out of a Microblaze header file and makes it non-static. The device ids table isn't merged because powerpc and microblaze use different default data. Signed-off-by: Grant Likely grant.lik...@secretlab.ca CC: Michal Simek mon...@monstr.eu CC: Grant Likely grant.lik...@secretlab.ca CC: Benjamin Herrenschmidt b...@kernel.crashing.org CC: Stephen Rothwell s...@canb.auug.org.au CC: microblaze-ucli...@itee.uq.edu.au CC: linuxppc-...@ozlabs.org --- arch/microblaze/include/asm/of_platform.h | 33 --- arch/microblaze/kernel/of_platform.c | 141 - arch/powerpc/include/asm/of_platform.h| 11 -- arch/powerpc/kernel/of_platform.c | 131 --- drivers/of/platform.c | 143 + include/linux/of_platform.h | 17 +++ 6 files changed, 179 insertions(+), 297 deletions(-) diff --git a/arch/microblaze/include/asm/of_platform.h b/arch/microblaze/include/asm/of_platform.h index 3749127..625003f 100644 --- a/arch/microblaze/include/asm/of_platform.h +++ b/arch/microblaze/include/asm/of_platform.h @@ -14,39 +14,6 @@ /* This is just here during the transition */ #include linux/of_platform.h -/* - * The list of OF IDs below is used for matching bus types in the - * system whose devices are to be exposed as of_platform_devices. - * - * This is the default list valid for most platforms. This file provides - * functions who can take an explicit list if necessary though - * - * The search is always performed recursively looking for children of - * the provided device_node and recursively if such a children matches - * a bus type in the list - */ - -static const struct of_device_id of_default_bus_ids[] = { - { .type = soc, }, - { .compatible = soc, }, - { .type = plb5, }, - { .type = plb4, }, - { .type = opb, }, - { .type = simple, }, - {}, -}; - -/* Platform devices and busses creation */ -extern struct of_device *of_platform_device_create(struct device_node *np, - const char *bus_id, - struct device *parent); -/* pseudo matches value to not do deep probe */ -#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1) - -extern int of_platform_bus_probe(struct device_node *root, - const struct of_device_id *matches, - struct device *parent); - extern struct of_device *of_find_device_by_phandle(phandle ph); extern void of_instantiate_rtc(void); diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c index ccf6f42..a07abdd 100644 --- a/arch/microblaze/kernel/of_platform.c +++ b/arch/microblaze/kernel/of_platform.c @@ -37,132 +37,27 @@ static int __init of_bus_driver_init(void) } postcore_initcall(of_bus_driver_init); -struct of_device *of_platform_device_create(struct device_node *np, - const char *bus_id, - struct device *parent) -{ - struct of_device *dev; - - dev = of_device_alloc(np, bus_id, parent); - if (!dev) - return NULL; - - dev-archdata.dma_mask = 0xUL; - dev-dev.bus = of_platform_bus_type; - - /* We do not fill the DMA ops for platform devices by default. -* This is currently the responsibility of the platform code -* to do such, possibly using a device notifier -*/ - - if (of_device_register(dev) != 0) { - of_device_free(dev); - return NULL; - } - - return dev; -} -EXPORT_SYMBOL(of_platform_device_create); - -/** - * of_platform_bus_create - Create an OF device for a bus node and all its - * children. Optionally recursively instanciate matching busses. - * @bus: device node of the bus to instanciate - * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to - * disallow recursive creation of child busses - */ -static int of_platform_bus_create(const struct device_node *bus, - const struct of_device_id *matches, - struct device *parent) -{ - struct device_node *child; - struct of_device *dev; - int rc = 0; - - for_each_child_of_node(bus, child) { - pr_debug( create child: %s\n, child-full_name); - dev = of_platform_device_create(child, NULL, parent); - if (dev == NULL) - rc = -ENOMEM; - else if (!of_match_node(matches, child)) - continue; - if (rc == 0) { -
[PATCH 3/5] of/address: Merge all of the bus translation code
Microblaze and PowerPC share a large chunk of code for translating OF device tree data into usable addresses. There aren't many differences between the two, so merge the codebase wholesale rather than trying to work out the independent bits. Signed-off-by: Grant Likely grant.lik...@secretlab.ca CC: Michal Simek mon...@monstr.eu CC: Wolfram Sang w.s...@pengutronix.de CC: Stephen Rothwell s...@canb.auug.org.au CC: Benjamin Herrenschmidt b...@kernel.crashing.org CC: microblaze-ucli...@itee.uq.edu.au CC: linuxppc-...@ozlabs.org --- arch/microblaze/include/asm/prom.h |4 arch/microblaze/kernel/prom_parse.c | 489 - arch/powerpc/include/asm/prom.h |4 arch/powerpc/kernel/prom_parse.c| 515 --- drivers/of/address.c| 517 +++ include/linux/of_address.h |4 6 files changed, 515 insertions(+), 1018 deletions(-) diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 644fa32..35cb3de 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -52,10 +52,6 @@ extern void pci_create_OF_bus_map(void); * OF address retreival translation */ -/* Translate an OF address block into a CPU physical address - */ -extern u64 of_translate_address(struct device_node *np, const u32 *addr); - /* Extract an address from a device, returns the region size and * the address space flags too. The PCI version uses a BAR number * instead of an absolute index diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c index 7cb5a98..1d610e6 100644 --- a/arch/microblaze/kernel/prom_parse.c +++ b/arch/microblaze/kernel/prom_parse.c @@ -10,213 +10,7 @@ #include asm/prom.h #include asm/pci-bridge.h -#define PRu64 %llx - -/* Max address size we deal with */ -#define OF_MAX_ADDR_CELLS 4 -#define OF_CHECK_COUNTS(na, ns)((na) 0 (na) = OF_MAX_ADDR_CELLS \ - (ns) 0) - -static struct of_bus *of_match_bus(struct device_node *np); - -/* Debug utility */ -#ifdef DEBUG -static void of_dump_addr(const char *s, const u32 *addr, int na) -{ - printk(KERN_INFO %s, s); - while (na--) - printk(KERN_INFO %08x, *(addr++)); - printk(KERN_INFO \n); -} -#else -static void of_dump_addr(const char *s, const u32 *addr, int na) { } -#endif - -/* Callbacks for bus specific translators */ -struct of_bus { - const char *name; - const char *addresses; - int (*match)(struct device_node *parent); - void(*count_cells)(struct device_node *child, - int *addrc, int *sizec); - u64 (*map)(u32 *addr, const u32 *range, - int na, int ns, int pna); - int (*translate)(u32 *addr, u64 offset, int na); - unsigned int(*get_flags)(const u32 *addr); -}; - -/* - * Default translator (generic bus) - */ - -static void of_bus_default_count_cells(struct device_node *dev, - int *addrc, int *sizec) -{ - if (addrc) - *addrc = of_n_addr_cells(dev); - if (sizec) - *sizec = of_n_size_cells(dev); -} - -static u64 of_bus_default_map(u32 *addr, const u32 *range, - int na, int ns, int pna) -{ - u64 cp, s, da; - - cp = of_read_number(range, na); - s = of_read_number(range + na + pna, ns); - da = of_read_number(addr, na); - - pr_debug(OF: default map, cp=PRu64, s=PRu64, da=PRu64\n, - cp, s, da); - - if (da cp || da = (cp + s)) - return OF_BAD_ADDR; - return da - cp; -} - -static int of_bus_default_translate(u32 *addr, u64 offset, int na) -{ - u64 a = of_read_number(addr, na); - memset(addr, 0, na * 4); - a += offset; - if (na 1) - addr[na - 2] = a 32; - addr[na - 1] = a 0xu; - - return 0; -} - -static unsigned int of_bus_default_get_flags(const u32 *addr) -{ - return IORESOURCE_MEM; -} - #ifdef CONFIG_PCI -/* - * PCI bus specific translator - */ - -static int of_bus_pci_match(struct device_node *np) -{ - /* vci is for the /chaos bridge on 1st-gen PCI powermacs */ - return !strcmp(np-type, pci) || !strcmp(np-type, vci); -} - -static void of_bus_pci_count_cells(struct device_node *np, - int *addrc, int *sizec) -{ - if (addrc) - *addrc = 3; - if (sizec) - *sizec = 2; -} - -static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna) -{ - u64 cp, s, da; - - /* Check address type match */ - if ((addr[0] ^ range[0]) 0x0300) - return OF_BAD_ADDR; - - /* Read address values, skipping high cell */ - cp = of_read_number(range + 1, na - 1); -
Re: [PATCH] kexec, ppc64: Wait for online/possible CPUs only.
On Tue, 2010-06-08 at 17:38 +1000, Matt Evans wrote: kexec_perpare_cpus_wait() iterates i through NR_CPUS to check paca[i].kexec_state of each to make sure they have quiesced. However now we have dynamic PACA allocation, paca[NR_CPUS] is not necessarily valid and we overrun the array; spurious cpu is not possible, ignoring errors result. This patch iterates for_each_online_cpu so stays within the bounds of paca[] -- and every CPU is now 'possible'. Signed-off-by: Matt Evans m...@ozlabs.org Looks good .. Cautiously-acked-by: Michael Ellerman mich...@ellerman.id.au - if (!cpu_online(i)) { - /* Fixme: this can be spinning in - * pSeries_secondary_wait with a paca - * waiting for it to go online. - */ - printk(kexec: cpu %d hw_cpu_id %d is not - online, ignoring\n, - i, paca[i].hw_cpu_id); - break; - } I don't see how the state in the Fixme could ever happen, but maybe Milton can seeing I think he wrote it? cheers signature.asc Description: This is a digitally signed message part ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 6/6] of/device: populate platform_device (of_device) resource table on allocation
On Tue, Jun 08, 2010 at 08:26:43AM -0600, Grant Likely wrote: [...] + dev = kzalloc(sizeof(*dev) + (sizeof(struct resource) * i), GFP_KERNEL); if (!dev) return NULL; - dev-dev.of_node = of_node_get(np); dev-dev.dma_mask = dev-archdata.dma_mask; dev-dev.parent = parent; dev-dev.release = of_release_dev; + /* Populate the resource table */ + if (num_irq || num_reg) { + dev-resource = (void*)dev[1]; This is ugly. Why not allocate the memory specifically for dev-resource? Is this because you plan to get rid of of_release_dev(), and the generic release_dev() won't know if it should free the dev-resource? There must be a better way to handle this. p.s. [Two Minutes Hate for Grant.] Just wonder what happened to of_gpio stuff? You blocked it in 2.6.34 for no reason saying I'll pick it into my OF tree before the 2.6.35 merge window and it's 2.6.36 merge window quite soon. It's still in origin/test-devicetree, which is obviously not -next. What is your plan now? Thanks, + dev-num_resources = num_reg + num_irq; + res = dev-resource; + for (i = 0; i num_reg; i++, res++) { + rc = of_address_to_resource(np, i, res); + WARN_ON(rc); + } + for (i = 0; i num_irq; i++, res++) { + rc = of_irq_to_resource(np, i, res); + WARN_ON(rc == NO_IRQ); + } + } + if (bus_id) dev_set_name(dev-dev, %s, bus_id); else -- Anton Vorontsov email: cbouatmai...@gmail.com irc://irc.freenode.net/bd2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 6/6] of/device: populate platform_device (of_device) resource table on allocation
On Tue, Jun 8, 2010 at 9:57 AM, Anton Vorontsov cbouatmai...@gmail.com wrote: On Tue, Jun 08, 2010 at 08:26:43AM -0600, Grant Likely wrote: [...] + dev = kzalloc(sizeof(*dev) + (sizeof(struct resource) * i), GFP_KERNEL); if (!dev) return NULL; - dev-dev.of_node = of_node_get(np); dev-dev.dma_mask = dev-archdata.dma_mask; dev-dev.parent = parent; dev-dev.release = of_release_dev; + /* Populate the resource table */ + if (num_irq || num_reg) { + dev-resource = (void*)dev[1]; This is ugly. Why not allocate the memory specifically for dev-resource? Is this because you plan to get rid of of_release_dev(), and the generic release_dev() won't know if it should free the dev-resource? There must be a better way to handle this. Allocating in one big block means less potential memory fragmentation, and the kernel can free it all at once. This is a common pattern. p.s. Just wonder what happened to of_gpio stuff? You blocked it in 2.6.34 for no reason saying I'll pick it into my OF tree before the 2.6.35 merge window and it's 2.6.36 merge window quite soon. It's in my test-devicetree branch. I'll be posting for 2nd review in the next few days and then adding to my devicetree-next branch probably before the end of the week. g. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 6/6] of/device: populate platform_device (of_device) resource table on allocation
On Tue, Jun 08, 2010 at 10:02:49AM -0600, Grant Likely wrote: On Tue, Jun 8, 2010 at 9:57 AM, Anton Vorontsov cbouatmai...@gmail.com wrote: On Tue, Jun 08, 2010 at 08:26:43AM -0600, Grant Likely wrote: [...] + dev = kzalloc(sizeof(*dev) + (sizeof(struct resource) * i), GFP_KERNEL); if (!dev) return NULL; - dev-dev.of_node = of_node_get(np); dev-dev.dma_mask = dev-archdata.dma_mask; dev-dev.parent = parent; dev-dev.release = of_release_dev; + /* Populate the resource table */ + if (num_irq || num_reg) { + dev-resource = (void*)dev[1]; This is ugly. Why not allocate the memory specifically for dev-resource? Is this because you plan to get rid of of_release_dev(), and the generic release_dev() won't know if it should free the dev-resource? There must be a better way to handle this. Allocating in one big block means less potential memory fragmentation, and the kernel can free it all at once. Are there any numbers of saved amount of memory so that we could compare? The less memory fragmentation is indeed potential, but introduction of obscure code is going on now at this precise moment. This is a common pattern. This can't be true because it produces ugly casts and fragile code all over the place -- which is exactly what everybody tries to avoid in the kernel. Such a pattern is common when a driver allocates e.g. tx and rx buffers (of the same type) together, and then split the buffer into two pointers. But I heard of no such pattern for 'struct device + struct resources' allocation without even some kind of _priv struct, which is surely something new, and ugly. If you really want to avoid (an unproven) memory fragmentation, you could do: struct of_device_with_resources { struct device dev; struct resource resourses[0]; }; This at least will get rid of the casts and incomprehensible dev-resource = (void*)dev[1]; construction. -- Anton Vorontsov email: cbouatmai...@gmail.com irc://irc.freenode.net/bd2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/2] sound/soc: mpc5200_psc_ac97: Use gpio pins for cold reset.
The implementation of the ac97 cold reset is flawed. If the sync and output lines are high when reset is asserted the attached ac97 device may go into test mode. Avoid this by reconfiguring the psc to gpio mode and generating the reset manually. Signed-off-by: Eric Millbrandt emillbra...@dekaresearch.com --- arch/powerpc/boot/dts/lite5200.dts |3 + arch/powerpc/boot/dts/lite5200b.dts |3 + arch/powerpc/boot/dts/pcm030.dts|3 + arch/powerpc/boot/dts/pcm032.dts|3 + sound/soc/fsl/mpc5200_dma.h |5 ++ sound/soc/fsl/mpc5200_psc_ac97.c| 83 +-- 6 files changed, 96 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts index 82ff2b1..cb4e49b 100644 --- a/arch/powerpc/boot/dts/lite5200.dts +++ b/arch/powerpc/boot/dts/lite5200.dts @@ -180,6 +180,9 @@ // compatible = fsl,mpc5200-psc-ac97; // cell-index = 1; // reg = 0x2200 0x100; + // gpios = gpio 7 0 /* AC97_1_RES */ + // gpio_simple 29 0 /* AC97_1_SYNC */ + // gpio_simple 31 0;/* AC97_1_SDATA_OUT */ // interrupts = 2 2 0; //}; diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts index e45a63b..1fb0ac7 100644 --- a/arch/powerpc/boot/dts/lite5200b.dts +++ b/arch/powerpc/boot/dts/lite5200b.dts @@ -184,6 +184,9 @@ // compatible = fsl,mpc5200b-psc-ac97,fsl,mpc5200-psc-ac97; // cell-index = 1; // reg = 0x2200 0x100; + // gpios = gpio 7 0 /* AC97_1_RES */ + // gpio_simple 29 0 /* AC97_1_SYNC */ + // gpio_simple 31 0;/* AC97_1_SDATA_OUT */ // interrupts = 2 2 0; //}; diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm030.dts index 8a4ec30..0085e0f 100644 --- a/arch/powerpc/boot/dts/pcm030.dts +++ b/arch/powerpc/boot/dts/pcm030.dts @@ -189,6 +189,9 @@ compatible = mpc5200b-psc-ac97,fsl,mpc5200b-psc-ac97; cell-index = 0; reg = 0x2000 0x100; + gpios = gpio 7 0 /* AC97_1_RES */ +gpio_simple 29 0 /* AC97_1_SYNC */ +gpio_simple 31 0;/* AC97_1_SDATA_OUT */ interrupts = 2 1 0; }; diff --git a/arch/powerpc/boot/dts/pcm032.dts b/arch/powerpc/boot/dts/pcm032.dts index 85d857a..76f86d3 100644 --- a/arch/powerpc/boot/dts/pcm032.dts +++ b/arch/powerpc/boot/dts/pcm032.dts @@ -189,6 +189,9 @@ compatible = fsl,mpc5200b-psc-ac97,fsl,mpc5200-psc-ac97; cell-index = 0; reg = 0x2000 0x100; + gpios = gpio 7 0 /* AC97_1_RES */ +gpio_simple 29 0 /* AC97_1_SYNC */ +gpio_simple 31 0;/* AC97_1_SDATA_OUT */ interrupts = 2 1 0; }; diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h index 22208b3..9fb0248 100644 --- a/sound/soc/fsl/mpc5200_dma.h +++ b/sound/soc/fsl/mpc5200_dma.h @@ -61,6 +61,11 @@ struct psc_dma { int id; unsigned int slots; + /* gpio pins locations for cold reset */ + int reset_gpio; + int sync_gpio; + int out_gpio; + /* per-stream data */ struct psc_dma_stream playback; struct psc_dma_stream capture; diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index e2ee220..bbbf860 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c @@ -9,8 +9,10 @@ * published by the Free Software Foundation. */ +#include linux/gpio.h #include linux/module.h #include linux/of_device.h +#include linux/of_gpio.h #include linux/of_platform.h #include linux/delay.h @@ -20,12 +22,17 @@ #include asm/time.h #include asm/delay.h +#include asm/mpc52xx.h #include asm/mpc52xx_psc.h #include mpc5200_dma.h #include mpc5200_psc_ac97.h #define DRV_NAME mpc5200-psc-ac97 +#define MPC52xx_GPIO_PSC1_MASK 0x7 +#define MPC52xx_GPIO_PSC2_MASK (0x74) +#define MPC52xx_AC97_PSC1 0x2 +#define MPC52xx_AC97_PSC2 (0x24) /* ALSA only supports a single AC97 device so static is recommend here */ static struct psc_dma *psc_dma; @@ -100,19 +107,69 @@ static void psc_ac97_warm_reset(struct snd_ac97 *ac97) { struct mpc52xx_psc __iomem *regs = psc_dma-psc_regs; + mutex_lock(psc_dma-mutex); + out_be32(regs-sicr, psc_dma-sicr | MPC52xx_PSC_SICR_AWR); udelay(3); out_be32(regs-sicr, psc_dma-sicr); + +
[PATCH 1/2] powerpc/5200: Export port-config
Allow device drivers to safely modify port-config. This allows device drivers access to gpio pins to manually bit-bang slave devices. Signed-off-by: Eric Millbrandt emillbra...@dekaresearch.com --- arch/powerpc/include/asm/mpc52xx.h |2 + arch/powerpc/platforms/52xx/mpc52xx_common.c | 61 ++ 2 files changed, 63 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/mpc52xx.h b/arch/powerpc/include/asm/mpc52xx.h index b664ce7..ebc5a3b 100644 --- a/arch/powerpc/include/asm/mpc52xx.h +++ b/arch/powerpc/include/asm/mpc52xx.h @@ -274,7 +274,9 @@ extern void mpc52xx_declare_of_platform_devices(void); extern void mpc52xx_map_common_devices(void); extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv); extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node); +extern unsigned int mpc52xx_read_port_config(void); extern void mpc52xx_restart(char *cmd); +extern int mpc52xx_write_port_config(u32 mux, int operation); /* mpc52xx_gpt.c */ struct mpc52xx_gpt_priv; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c index a46bad0..77c685a 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c @@ -37,6 +37,11 @@ static struct of_device_id mpc52xx_bus_ids[] __initdata = { {} }; +static struct of_device_id mpc52xx_gpio_simple[] = { + { .compatible = fsl,mpc5200-gpio, }, + {} +}; + /* * This variable is mapped in mpc52xx_map_wdt() and used in mpc52xx_restart(). * Permanent mapping is required because mpc52xx_restart() can be called @@ -82,6 +87,15 @@ mpc5200_setup_xlb_arbiter(void) iounmap(xlb); } +/* + * This variable is mapped in mpc52xx_write_port_config() and + * mpc52xx_read_port_config(). Permanent mapping is required because + * mpc52xx_map_and_lock_port_config() can be called from interrupt context + * while node mapping (which calls ioremap()) cannot be used at such point. + */ +static DEFINE_SPINLOCK(mpc52xx_port_config_lock); +static u32 __iomem *port_config; + /** * mpc52xx_declare_of_platform_devices: register internal devices and children * of the localplus bus to the of_platform @@ -117,6 +131,7 @@ void __init mpc52xx_map_common_devices(void) { struct device_node *np; + const u32 *regaddr; /* mpc52xx_wdt is mapped here and used in mpc52xx_restart, * possibly from a interrupt context. wdt is only implement @@ -135,6 +150,13 @@ mpc52xx_map_common_devices(void) np = of_find_matching_node(NULL, mpc52xx_cdm_ids); mpc52xx_cdm = of_iomap(np, 0); of_node_put(np); + + /* port_config register */ + np = of_find_matching_node(NULL, mpc52xx_gpio_simple); + regaddr = of_get_address(np, 0, NULL, NULL); + port_config = ioremap((u32) of_translate_address(np, regaddr), 0x4); + + of_node_put(np); } /** @@ -233,3 +255,42 @@ mpc52xx_restart(char *cmd) while (1); } + +/** + * mpc52xx_write_port_config: Allow mutually exclusive access to the + * port_config register + * + * @newmux: value to write to port_config + * @operation: set to 0 for | or 1 for + */ +int mpc52xx_write_port_config(u32 newmux, int operation) +{ + unsigned long flags; + u32 mux; + + if (!port_config) + return -ENODEV; + + spin_lock_irqsave(mpc52xx_port_config_lock, flags); + mux = in_be32(port_config); + if (operation) + out_be32(port_config, mux newmux); + else + out_be32(port_config, mux | newmux); + spin_unlock_irqrestore(mpc52xx_port_config_lock, flags); + + return 0; +} +EXPORT_SYMBOL(mpc52xx_write_port_config); + +/** + * mpc52xx_read_port_config: Return the value of port_config + */ +unsigned int mpc52xx_read_port_config(void) +{ + if (!port_config) + return -ENODEV; + + return in_be32(port_config); +} +EXPORT_SYMBOL(mpc52xx_read_port_config); -- 1.6.3.1 This e-mail and the information, including any attachments, it contains are intended to be a confidential communication only to the person or entity to whom it is addressed and may contain information that is privileged. If the reader of this message is not the intended recipient, you are hereby notified that any dissemination, distribution or copying of this communication is strictly prohibited. If you have received this communication in error, please immediately notify the sender and destroy the original message. Thank you. Please consider the environment before printing this email. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 0/2] mpc5200 ac97 gpio reset
These patches reimplement the reset fuction in the ac97 to use gpio pins instead of using the mpc5200 ac97 reset functionality in the psc. This avoids a problem in which attached ac97 devices go into test mode appear unresponsive. These patches were tested on a pcm030 baseboard and on custom hardware with a wm9715 audio codec/touchscreen controller. Eric Millbrandt --- Eric Millbrandt (2): powerpc/5200: Export port-config sound/soc: mpc5200_psc_ac97: Use gpio pins for cold reset. arch/powerpc/boot/dts/lite5200.dts |3 + arch/powerpc/boot/dts/lite5200b.dts |3 + arch/powerpc/boot/dts/pcm030.dts |3 + arch/powerpc/boot/dts/pcm032.dts |3 + arch/powerpc/include/asm/mpc52xx.h |2 + arch/powerpc/platforms/52xx/mpc52xx_common.c | 61 +++ sound/soc/fsl/mpc5200_dma.h |5 ++ sound/soc/fsl/mpc5200_psc_ac97.c | 83 - 8 files changed, 159 insertions(+), 4 deletions(-) -DISCLAIMER: an automatically appended disclaimer may follow. By posting- -to a public e-mail mailing list I hereby grant permission to distribute- -and copy this message.- This e-mail and the information, including any attachments, it contains are intended to be a confidential communication only to the person or entity to whom it is addressed and may contain information that is privileged. If the reader of this message is not the intended recipient, you are hereby notified that any dissemination, distribution or copying of this communication is strictly prohibited. If you have received this communication in error, please immediately notify the sender and destroy the original message. Thank you. Please consider the environment before printing this email. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 6/6] of/device: populate platform_device (of_device) resource table on allocation
On Tue, Jun 8, 2010 at 10:46 AM, Anton Vorontsov cbouatmai...@gmail.com wrote: On Tue, Jun 08, 2010 at 10:02:49AM -0600, Grant Likely wrote: On Tue, Jun 8, 2010 at 9:57 AM, Anton Vorontsov cbouatmai...@gmail.com wrote: On Tue, Jun 08, 2010 at 08:26:43AM -0600, Grant Likely wrote: [...] + dev = kzalloc(sizeof(*dev) + (sizeof(struct resource) * i), GFP_KERNEL); if (!dev) return NULL; - dev-dev.of_node = of_node_get(np); dev-dev.dma_mask = dev-archdata.dma_mask; dev-dev.parent = parent; dev-dev.release = of_release_dev; + /* Populate the resource table */ + if (num_irq || num_reg) { + dev-resource = (void*)dev[1]; This is ugly. Why not allocate the memory specifically for dev-resource? Is this because you plan to get rid of of_release_dev(), and the generic release_dev() won't know if it should free the dev-resource? There must be a better way to handle this. Allocating in one big block means less potential memory fragmentation, and the kernel can free it all at once. Are there any numbers of saved amount of memory so that we could compare? The less memory fragmentation is indeed potential, but introduction of obscure code is going on now at this precise moment. It's not obscure. It's smaller and simpler code with fewer error paths. This is a common pattern. This can't be true because it produces ugly casts and fragile code all over the place -- which is exactly what everybody tries to avoid in the kernel. Fragile? How? var[1] *always* gives you a pointer to the first address after a structure. If the structure changes, then so does the offset. Heck, if the type of 'var' changes, then the offset changes in kind too. If anything, I should have also used sizeof(*res) in the kzalloc call so that the allocated size is protected against a type change to 'res' too. If you prefer, I can move the dev-resource assignment to immediately after the kzalloc to keep everything contained within 4 lines of each other. Such a pattern is common when a driver allocates e.g. tx and rx buffers (of the same type) together, and then split the buffer into two pointers. tx rx buffers are different because they must be DMAable. That imposes alignment requirements with kzalloc() guarantees. But I heard of no such pattern for 'struct device + struct resources' allocation without even some kind of _priv struct, which is surely something new, and ugly. git grep '\*).*[a-z1-9_]*\[1\]' g. -- Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 6/6] of/device: populate platform_device (of_device) resource table on allocation
On Tue, Jun 08, 2010 at 12:41:47PM -0600, Grant Likely wrote: [...] This is a common pattern. This can't be true because it produces ugly casts and fragile code all over the place -- which is exactly what everybody tries to avoid in the kernel. Fragile? How? var[1] *always* gives you a pointer to the first address after a structure. If the structure changes, then so does the offset. Heck, if the type of 'var' changes, then the offset changes in kind too. If anything, I should have also used sizeof(*res) in the kzalloc call so that the allocated size is protected against a type change to 'res' too. You just introduced an unnamed structure of device + resources, it isn't declared anywhere but in the code itself (either via foo[1] or buf + sizeof(*foo)). You're not the only one who hacks (or at least have to understand) the OF stuff, so let's try keep this stuff readable? I told you several ways of how to improve the code (based on the ideas from drivers/base/, so the ideas aren't even mine, fwiw). If you prefer, I can move the dev-resource assignment to immediately after the kzalloc to keep everything contained within 4 lines of each other. Sure, that would be better, but I already said what would I really prefer, i.e. - A dedicated allocation; - Or, at least, the same thing as drivers/base/platform.c does: platform_object { platform_device; name[1]; }; But I heard of no such pattern for 'struct device + struct resources' allocation without even some kind of _priv struct, which is surely something new, and ugly. git grep '\*).*[a-z1-9_]*\[1\]' Ugh? This produces a lot of false positives. But OK, let's run it. ~/linux-2.6$ git grep '\*).*[a-z1-9_]*\[1\]' | wc -l 164 ^^^ Now let's presume that half of it (and not just a few hits) is the ugly hacks that we're talking about. Then compare: ~/linux-2.6$ git grep 'struct.*_priv' | wc -l 22448 ^^^ this is a common pattern. -- Anton Vorontsov email: cbouatmai...@gmail.com irc://irc.freenode.net/bd2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/3] powerpc/85xx: Fix SWIOTLB initalization for MPC85xxMDS boards
The code inside '#ifdef CONFIG_QUICC_ENGINE' makes the mpc85xx_mds_setup_arch() return early if no QE nodes present, and so SWIOTLB is never initialized. This patch fixes the issue by moving SWIOTLB code above QE. Signed-off-by: Anton Vorontsov avoront...@mvista.com --- arch/powerpc/platforms/85xx/mpc85xx_mds.c | 16 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 8fe87fc..35ab2b4 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -202,6 +202,14 @@ static void __init mpc85xx_mds_setup_arch(void) mpc85xx_smp_init(); #endif +#ifdef CONFIG_SWIOTLB + if (lmb_end_of_DRAM() max) { + ppc_swiotlb_enable = 1; + set_pci_dma_ops(swiotlb_dma_ops); + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; + } +#endif + #ifdef CONFIG_QUICC_ENGINE np = of_find_compatible_node(NULL, NULL, fsl,qe); if (!np) { @@ -323,14 +331,6 @@ static void __init mpc85xx_mds_setup_arch(void) } #endif /* CONFIG_QUICC_ENGINE */ - -#ifdef CONFIG_SWIOTLB - if (lmb_end_of_DRAM() max) { - ppc_swiotlb_enable = 1; - set_pci_dma_ops(swiotlb_dma_ops); - ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; - } -#endif } -- 1.7.0.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/3] powerpc/85xx: Fix booting for P1021MDS boards
P1021 processors have no dedicated ROM to store the QE microcode, so the fimrware is stored externally, and it is U-Boot responsibility to load it. It might be that the board is booting without QE, e.g. currently U-Boot doesn't support QE for P1021MDS boards, which means that QE isn't initialized, and so the board hangs early at boot. This patch fixes the issue by marking QE as disabled and checking the state in the probing code. U-Boot should fixup the state if it initialized the QE. Signed-off-by: Anton Vorontsov avoront...@mvista.com --- arch/powerpc/boot/dts/p1021mds.dts|1 + arch/powerpc/platforms/85xx/mpc85xx_mds.c | 43 + 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/boot/dts/p1021mds.dts b/arch/powerpc/boot/dts/p1021mds.dts index 7fad2df..ad5b852 100644 --- a/arch/powerpc/boot/dts/p1021mds.dts +++ b/arch/powerpc/boot/dts/p1021mds.dts @@ -617,6 +617,7 @@ bus-frequency = 0; fsl,qe-num-riscs = 1; fsl,qe-num-snums = 28; + status = disabled; /* no firmware loaded */ qeic: interrupt-control...@80 { interrupt-controller; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 35ab2b4..9dadcff 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -158,6 +158,29 @@ static int mpc8568_mds_phy_fixups(struct phy_device *phydev) extern void __init mpc85xx_smp_init(void); #endif +#ifdef CONFIG_QUICC_ENGINE +static struct of_device_id mpc85xx_qe_ids[] __initdata = { + { .type = qe, }, + { .compatible = fsl,qe, }, + { }, +}; + +static void __init mpc85xx_publish_qe_devices(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, fsl,qe); + if (!of_device_is_available(np)) { + of_node_put(np); + return; + } + + of_platform_bus_probe(NULL, mpc85xx_qe_ids, NULL); +} +#else +static void __init mpc85xx_publish_qe_devices(void) { } +#endif /* CONFIG_QUICC_ENGINE */ + static void __init mpc85xx_mds_setup_arch(void) { struct device_node *np; @@ -218,6 +241,11 @@ static void __init mpc85xx_mds_setup_arch(void) return; } + if (!of_device_is_available(np)) { + of_node_put(np); + return; + } + qe_reset(); of_node_put(np); @@ -369,8 +397,6 @@ static struct of_device_id mpc85xx_ids[] = { { .type = soc, }, { .compatible = soc, }, { .compatible = simple-bus, }, - { .type = qe, }, - { .compatible = fsl,qe, }, { .compatible = gianfar, }, { .compatible = fsl,rapidio-delta, }, { .compatible = fsl,mpc8548-guts, }, @@ -382,8 +408,6 @@ static struct of_device_id p1021_ids[] = { { .type = soc, }, { .compatible = soc, }, { .compatible = simple-bus, }, - { .type = qe, }, - { .compatible = fsl,qe, }, { .compatible = gianfar, }, {}, }; @@ -395,16 +419,16 @@ static int __init mpc85xx_publish_devices(void) if (machine_is(mpc8569_mds)) simple_gpiochip_init(fsl,mpc8569mds-bcsr-gpio); - /* Publish the QE devices */ of_platform_bus_probe(NULL, mpc85xx_ids, NULL); + mpc85xx_publish_qe_devices(); return 0; } static int __init p1021_publish_devices(void) { - /* Publish the QE devices */ of_platform_bus_probe(NULL, p1021_ids, NULL); + mpc85xx_publish_qe_devices(); return 0; } @@ -443,12 +467,19 @@ static void __init mpc85xx_mds_pic_init(void) mpic_init(mpic); #ifdef CONFIG_QUICC_ENGINE + np = of_find_compatible_node(NULL, NULL, fsl,qe); + if (!of_device_is_available(np)) { + of_node_put(np); + return; + } + np = of_find_compatible_node(NULL, NULL, fsl,qe-ic); if (!np) { np = of_find_node_by_type(NULL, qeic); if (!np) return; } + if (machine_is(p1021_mds)) qe_ic_init(np, 0, qe_ic_cascade_low_mpic, qe_ic_cascade_high_mpic); -- 1.7.0.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 3/3] powerpc/85xx: Cleanup QE initialization for MPC85xxMDS boards
The mpc85xx_mds_setup_arch() function is incomprehensible and unmaintainable. Factor out all QE specific stuff into mpc85xx_mds_qe_init() and mpc85xx_mds_reset_ucc_phys(). Also move QE stuff out of mpc85xx_mds_pic_init(). The diff is unreadable, but only because the code was so. ;-) It should be better now, and less indented. Signed-off-by: Anton Vorontsov avoront...@mvista.com --- arch/powerpc/platforms/85xx/mpc85xx_mds.c | 272 +++-- 1 files changed, 143 insertions(+), 129 deletions(-) diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 9dadcff..c8be7b5 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -177,63 +177,89 @@ static void __init mpc85xx_publish_qe_devices(void) of_platform_bus_probe(NULL, mpc85xx_qe_ids, NULL); } -#else -static void __init mpc85xx_publish_qe_devices(void) { } -#endif /* CONFIG_QUICC_ENGINE */ -static void __init mpc85xx_mds_setup_arch(void) +static void __init mpc85xx_mds_reset_ucc_phys(void) { struct device_node *np; - static u8 __iomem *bcsr_regs = NULL; -#ifdef CONFIG_PCI - struct pci_controller *hose; -#endif - dma_addr_t max = 0x; - - if (ppc_md.progress) - ppc_md.progress(mpc85xx_mds_setup_arch(), 0); + static u8 __iomem *bcsr_regs; /* Map BCSR area */ np = of_find_node_by_name(NULL, bcsr); - if (np != NULL) { - struct resource res; + if (!np) + return; - of_address_to_resource(np, 0, res); - bcsr_regs = ioremap(res.start, res.end - res.start +1); - of_node_put(np); - } + bcsr_regs = of_iomap(np, 0); + of_node_put(np); + if (!bcsr_regs) + return; -#ifdef CONFIG_PCI - for_each_node_by_type(np, pci) { - if (of_device_is_compatible(np, fsl,mpc8540-pci) || - of_device_is_compatible(np, fsl,mpc8548-pcie)) { - struct resource rsrc; - of_address_to_resource(np, 0, rsrc); - if ((rsrc.start 0xf) == 0x8000) - fsl_add_bridge(np, 1); - else - fsl_add_bridge(np, 0); + if (machine_is(mpc8568_mds)) { +#define BCSR_UCC1_GETH_EN (0x1 7) +#define BCSR_UCC2_GETH_EN (0x1 7) +#define BCSR_UCC1_MODE_MSK (0x3 4) +#define BCSR_UCC2_MODE_MSK (0x3 0) - hose = pci_find_hose_for_OF_device(np); - max = min(max, hose-dma_window_base_cur + - hose-dma_window_size); + /* Turn off UCC1 UCC2 */ + clrbits8(bcsr_regs[8], BCSR_UCC1_GETH_EN); + clrbits8(bcsr_regs[9], BCSR_UCC2_GETH_EN); + + /* Mode is RGMII, all bits clear */ + clrbits8(bcsr_regs[11], BCSR_UCC1_MODE_MSK | +BCSR_UCC2_MODE_MSK); + + /* Turn UCC1 UCC2 on */ + setbits8(bcsr_regs[8], BCSR_UCC1_GETH_EN); + setbits8(bcsr_regs[9], BCSR_UCC2_GETH_EN); + } else if (machine_is(mpc8569_mds)) { +#define BCSR7_UCC12_GETHnRST (0x1 2) +#define BCSR8_UEM_MARVELL_RST (0x1 1) +#define BCSR_UCC_RGMII (0x1 6) +#define BCSR_UCC_RTBI (0x1 5) + /* +* U-Boot mangles interrupt polarity for Marvell PHYs, +* so reset built-in and UEM Marvell PHYs, this puts +* the PHYs into their normal state. +*/ + clrbits8(bcsr_regs[7], BCSR7_UCC12_GETHnRST); + setbits8(bcsr_regs[8], BCSR8_UEM_MARVELL_RST); + + setbits8(bcsr_regs[7], BCSR7_UCC12_GETHnRST); + clrbits8(bcsr_regs[8], BCSR8_UEM_MARVELL_RST); + + for (np = NULL; (np = of_find_compatible_node(np, + network, + ucc_geth)) != NULL;) { + const unsigned int *prop; + int ucc_num; + + prop = of_get_property(np, cell-index, NULL); + if (prop == NULL) + continue; + + ucc_num = *prop - 1; + + prop = of_get_property(np, phy-connection-type, NULL); + if (prop == NULL) + continue; + + if (strcmp(rtbi, (const char *)prop) == 0) + clrsetbits_8(bcsr_regs[7 + ucc_num], + BCSR_UCC_RGMII, BCSR_UCC_RTBI); } + } else if (machine_is(p1021_mds)) { +#define BCSR11_ENET_MICRST (0x1 5) + /* Reset Micrel PHY */ +
Re: [PATCH 0/2] mpc5200 ac97 gpio reset
On Tue, Jun 8, 2010 at 12:46 PM, Eric Millbrandt emillbra...@dekaresearch.com wrote: These patches reimplement the reset fuction in the ac97 to use gpio pins instead of using the mpc5200 ac97 reset functionality in the psc. This avoids a problem in which attached ac97 devices go into test mode appear unresponsive. I'm aware of this problem but I was unable to solve it when I first wrote the driver. I didn't have access to a scope so I wasn't able to figure out what was causing the lock up. I worked around it by looping in reset until the chip did actually reset, but Mark wouldn't let me submit that code. A while ago Maximilian Mueth maximilian.mu...@mp-ndt.de sent me a note saying another solution was to configure the PSC into AC97 mode in uboot. His impression was that uboot was setting PSC into its default mode. Then Linux booted and set the PSC into AC97 mode. The transition from default mode into AC97 mode caused glitches on the AC97 reset pins and triggered test mode. Would making a change in uboot be a better solution? Eric, can you verify if changing uboot also fixes the problem? I'm glad were finally getting to the root cause of the problem. These patches were tested on a pcm030 baseboard and on custom hardware with a wm9715 audio codec/touchscreen controller. Eric Millbrandt --- Eric Millbrandt (2): powerpc/5200: Export port-config sound/soc: mpc5200_psc_ac97: Use gpio pins for cold reset. arch/powerpc/boot/dts/lite5200.dts | 3 + arch/powerpc/boot/dts/lite5200b.dts | 3 + arch/powerpc/boot/dts/pcm030.dts | 3 + arch/powerpc/boot/dts/pcm032.dts | 3 + arch/powerpc/include/asm/mpc52xx.h | 2 + arch/powerpc/platforms/52xx/mpc52xx_common.c | 61 +++ sound/soc/fsl/mpc5200_dma.h | 5 ++ sound/soc/fsl/mpc5200_psc_ac97.c | 83 - 8 files changed, 159 insertions(+), 4 deletions(-) -DISCLAIMER: an automatically appended disclaimer may follow. By posting- -to a public e-mail mailing list I hereby grant permission to distribute- -and copy this message.- This e-mail and the information, including any attachments, it contains are intended to be a confidential communication only to the person or entity to whom it is addressed and may contain information that is privileged. If the reader of this message is not the intended recipient, you are hereby notified that any dissemination, distribution or copying of this communication is strictly prohibited. If you have received this communication in error, please immediately notify the sender and destroy the original message. Thank you. Please consider the environment before printing this email. -- Jon Smirl jonsm...@gmail.com ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev