Re: [PATCH] powerpc: Add legacy PCI access via sysfs (v3)

2008-10-15 Thread Jesse Barnes
On Monday, October 13, 2008 5:55 pm Benjamin Herrenschmidt wrote:
 This patch adds support for legacy_io and legacy_mem files in
 bus class directories in sysfs for powerpc

 Signed-off-by: Benjamin Herrenschmidt [EMAIL PROTECTED]

Ok, applied this one.  Should be pushing to Linus soon.

Thanks,
Jesse
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


Re: [PATCH] powerpc: Add legacy PCI access via sysfs (v3)

2008-10-15 Thread Benjamin Herrenschmidt
On Wed, 2008-10-15 at 05:16 -0700, Jesse Barnes wrote:
 On Monday, October 13, 2008 5:55 pm Benjamin Herrenschmidt wrote:
  This patch adds support for legacy_io and legacy_mem files in
  bus class directories in sysfs for powerpc
 
  Signed-off-by: Benjamin Herrenschmidt [EMAIL PROTECTED]
 
 Ok, applied this one.  Should be pushing to Linus soon.

Thanks !

Ben.


___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev


[PATCH] powerpc: Add legacy PCI access via sysfs (v3)

2008-10-13 Thread Benjamin Herrenschmidt
This patch adds support for legacy_io and legacy_mem files in
bus class directories in sysfs for powerpc

Signed-off-by: Benjamin Herrenschmidt [EMAIL PROTECTED]
---

This is version 3, this time after doing a quilt ref and thus
getting a patch that actually useful. Sorry about the mishap.

 arch/powerpc/include/asm/pci-bridge.h |7 +
 arch/powerpc/include/asm/pci.h|   11 ++
 arch/powerpc/kernel/pci-common.c  |  136 +-
 3 files changed, 153 insertions(+), 1 deletion(-)

--- linux-work.orig/arch/powerpc/include/asm/pci.h  2008-10-03 
19:47:08.0 +1000
+++ linux-work/arch/powerpc/include/asm/pci.h   2008-10-10 10:50:46.0 
+1100
@@ -123,6 +123,16 @@ int pci_mmap_page_range(struct pci_dev *
 /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
 #define HAVE_PCI_MMAP  1
 
+extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val,
+  size_t count);
+extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,
+  size_t count);
+extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
+ struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state);
+
+#define HAVE_PCI_LEGACY1
+
 #if defined(CONFIG_PPC64) || defined(CONFIG_NOT_COHERENT_CACHE)
 /*
  * For 64-bit kernels, pci_unmap_{single,page} is not a nop.
@@ -226,5 +236,6 @@ extern void pci_resource_to_user(const s
 extern void pcibios_do_bus_setup(struct pci_bus *bus);
 extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus);
 
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_POWERPC_PCI_H */
Index: linux-work/arch/powerpc/kernel/pci-common.c
===
--- linux-work.orig/arch/powerpc/kernel/pci-common.c2008-10-03 
19:47:08.0 +1000
+++ linux-work/arch/powerpc/kernel/pci-common.c 2008-10-14 11:32:38.0 
+1100
@@ -452,7 +452,8 @@ pgprot_t pci_phys_mem_access_prot(struct
pci_dev_put(pdev);
}
 
-   DBG(non-PCI map for %lx, prot: %lx\n, offset, prot);
+   DBG(non-PCI map for %llx, prot: %lx\n,
+   (unsigned long long)offset, prot);
 
return __pgprot(prot);
 }
@@ -491,6 +492,131 @@ int pci_mmap_page_range(struct pci_dev *
return ret;
 }
 
+/* This provides legacy IO read access on a bus */
+int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size)
+{
+   unsigned long offset;
+   struct pci_controller *hose = pci_bus_to_host(bus);
+   struct resource *rp = hose-io_resource;
+   void __iomem *addr;
+
+   /* Check if port can be supported by that bus. We only check
+* the ranges of the PHB though, not the bus itself as the rules
+* for forwarding legacy cycles down bridges are not our problem
+* here. So if the host bridge supports it, we do it.
+*/
+   offset = (unsigned long)hose-io_base_virt - _IO_BASE;
+   offset += port;
+
+   if (!(rp-flags  IORESOURCE_IO))
+   return -ENXIO;
+   if (offset  rp-start || (offset + size)  rp-end)
+   return -ENXIO;
+   addr = hose-io_base_virt + port;
+
+   switch(size) {
+   case 1:
+   *((u8 *)val) = in_8(addr);
+   return 1;
+   case 2:
+   if (port  1)
+   return -EINVAL;
+   *((u16 *)val) = in_le16(addr);
+   return 2;
+   case 4:
+   if (port  3)
+   return -EINVAL;
+   *((u32 *)val) = in_le32(addr);
+   return 4;
+   }
+   return -EINVAL;
+}
+
+/* This provides legacy IO write access on a bus */
+int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size)
+{
+   unsigned long offset;
+   struct pci_controller *hose = pci_bus_to_host(bus);
+   struct resource *rp = hose-io_resource;
+   void __iomem *addr;
+
+   /* Check if port can be supported by that bus. We only check
+* the ranges of the PHB though, not the bus itself as the rules
+* for forwarding legacy cycles down bridges are not our problem
+* here. So if the host bridge supports it, we do it.
+*/
+   offset = (unsigned long)hose-io_base_virt - _IO_BASE;
+   offset += port;
+
+   if (!(rp-flags  IORESOURCE_IO))
+   return -ENXIO;
+   if (offset  rp-start || (offset + size)  rp-end)
+   return -ENXIO;
+   addr = hose-io_base_virt + port;
+
+   /* WARNING: The generic code is idiotic. It gets passed a pointer
+* to what can be a 1, 2 or 4 byte quantity and always reads that
+* as a u32, which means that we have to correct the location of
+* the data read within those 32 bits for size 1 and 2
+*/
+   switch(size) {
+   case 1:
+   out_8(addr, val  24);
+   return