ar71xx: add initial support for 3.2
[openwrt.git] / target / linux / ar71xx / patches-3.2 / 115-MIPS-ath79-allow-to-use-board-specific-pci_plat_dev_.patch
diff --git a/target/linux/ar71xx/patches-3.2/115-MIPS-ath79-allow-to-use-board-specific-pci_plat_dev_.patch b/target/linux/ar71xx/patches-3.2/115-MIPS-ath79-allow-to-use-board-specific-pci_plat_dev_.patch
new file mode 100644 (file)
index 0000000..4a5ec6c
--- /dev/null
@@ -0,0 +1,143 @@
+From 83d74abc7d549f5d6292b0474be080983239c0bd Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg@openwrt.org>
+Date: Sun, 20 Nov 2011 10:29:36 +0100
+Subject: [PATCH 15/35] MIPS: ath79: allow to use board specific pci_plat_dev_init functions
+
+Th current implementation causes NULL pointer dereference
+if 'pci_data' is not set:
+
+pci 0000:00:00.0: BAR 0: assigned [mem 0x10000000-0x1000ffff 64bit]
+pci 0000:00:00.0: BAR 0: set to [mem 0x10000000-0x1000ffff 64bit] (PCI
+address [0x10000000-0x1000ffff])
+CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == 802daca0, ra == 802e78a4
+Oops[#1]:
+Cpu 0
+$ 0   : 00000000 80420000 00000000 00000000
+$ 4   : 00000000 00000000 00000001 00000001
+$ 8   : 00000001 0000032c 81c54700 00000001
+$12   : 0000032d 0000000f 00000000 ffffffff
+$16   : 81c14c00 00000001 802dac74 80195f98
+$20   : 802ea050 00000000 00000000 00000000
+$24   : 00000003 800617f0
+$28   : 81c20000 81c21e70 00000000 802e78a4
+Hi    : 00000000
+Lo    : 4190ab00
+epc   : 802daca0 0x802daca0
+    Not tainted
+ra    : 802e78a4 0x802e78a4
+Status: 1000c003    KERNEL EXL IE
+Cause : 00800008
+BadVA : 00000000
+PrId  : 00019374 (MIPS 24Kc)
+Modules linked in:
+Process swapper (pid: 1, threadinfo=81c20000, task=81c18000, tls=00000000)
+Stack : 00000000 8027d5d8 802e8ae0 00000000 01000000 802e8b5c 81c50600 00000000
+        802ff290 00000000 80420000 802ea0bc 00000000 00000000 80420000 802ff290
+        80420000 80060930 33390000 00000000 00002308 80140a80 00000028 802d0000
+        00000000 800ba024 802ff004 802ff0c8 802ff290 00000000 00000000 00000000
+        00000000 802d897c 01234567 7f827068 00000000 0045f798 00460000 00000000
+
+This can be avoided by calling the 'ar724x_pci_add_data'
+function from the board specific setup code. However it
+makes no sense to use that function for every board,
+especially when the board does not needs to set the
+platform_data field of any PCI device.
+
+The patch allows the board setup code to specify a board
+specific function if that is required.
+
+Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
+
+v2: - no changes
+
+The pci_irq_map function can throw another NULL pointer
+dereference, that will be fixed in a subsequent patch.
+---
+ arch/mips/ath79/mach-ubnt-xm.c |   13 ++++++++++++-
+ arch/mips/ath79/pci.c          |   14 ++++++++------
+ arch/mips/ath79/pci.h          |    4 +++-
+ 3 files changed, 23 insertions(+), 8 deletions(-)
+
+--- a/arch/mips/ath79/mach-ubnt-xm.c
++++ b/arch/mips/ath79/mach-ubnt-xm.c
+@@ -85,16 +85,27 @@ static struct ath9k_platform_data ubnt_x
+ static struct ar724x_pci_data ubnt_xm_pci_data[] = {
+       {
+               .irq    = ATH79_PCI_IRQ(0),
+-              .pdata  = &ubnt_xm_eeprom_data,
+       },
+ };
++static int ubnt_xm_pci_plat_dev_init(struct pci_dev *dev)
++{
++      switch (PCI_SLOT(dev->devfn)) {
++      case 0:
++              dev->dev.platform_data = &ubnt_xm_eeprom_data;
++              break;
++      }
++
++      return 0;
++}
++
+ static void __init ubnt_xm_pci_init(void)
+ {
+       memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
+              sizeof(ubnt_xm_eeprom_data.eeprom_data));
+       ar724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data));
++      ath79_pci_set_plat_dev_init(ubnt_xm_pci_plat_dev_init);
+       ath79_register_pci();
+ }
+ #else
+--- a/arch/mips/ath79/pci.c
++++ b/arch/mips/ath79/pci.c
+@@ -14,6 +14,7 @@
+ #include <asm/mach-ath79/pci.h>
+ #include "pci.h"
++static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev);
+ static struct ar724x_pci_data *pci_data;
+ static int pci_data_size;
+@@ -38,14 +39,15 @@ int __init pcibios_map_irq(const struct 
+ int pcibios_plat_dev_init(struct pci_dev *dev)
+ {
+-      unsigned int devfn = dev->devfn;
+-
+-      if (devfn > pci_data_size - 1)
+-              return PCIBIOS_DEVICE_NOT_FOUND;
++      if (ath79_pci_plat_dev_init)
++              return ath79_pci_plat_dev_init(dev);
+-      dev->dev.platform_data = pci_data[devfn].pdata;
++      return 0;
++}
+-      return PCIBIOS_SUCCESSFUL;
++void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev))
++{
++      ath79_pci_plat_dev_init = func;
+ }
+ int __init ath79_register_pci(void)
+--- a/arch/mips/ath79/pci.h
++++ b/arch/mips/ath79/pci.h
+@@ -13,14 +13,16 @@
+ struct ar724x_pci_data {
+       int irq;
+-      void *pdata;
+ };
+ void ar724x_pci_add_data(struct ar724x_pci_data *data, int size);
+ #ifdef CONFIG_PCI
++void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev));
+ int ath79_register_pci(void);
+ #else
++static inline void
++ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *)) {}
+ static inline int ath79_register_pci(void) { return 0; }
+ #endif
This page took 0.027374 seconds and 4 git commands to generate.