* [PATCH 5/27] powerpc: Make pci_read_irq_line the default
From: Benjamin Herrenschmidt @ 2006-11-06 7:05 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1162796738.274582.277491064706.qpush@grosgo>
This patch reworks the way IRQs are fixed up on PCI for arch powerpc.
It makes pci_read_irq_line() called by default in the PCI code for
devices that are probed, and add an optional per-device fixup in
ppc_md for platforms that really need to correct what they obtain
from pci_read_irq_line().
It also removes ppc_md.irq_bus_setup which was only used by pSeries
and should not be needed anymore.
I've also removed the pSeries s7a workaround as it can't work with
the current interrupt code anyway. I'm trying to get one of these
machines working so I can test a proper fix for that problem.
I also haven't updated the old-style fixup code from 85xx_cds.c
because it's actually buggy :) It assigns pci_dev->irq hard coded
numbers which is no good with the new IRQ mapping code. It should
at least use irq_create_mapping(NULL, hard_coded_number); and possibly
also set_irq_type() to set them as level low.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
arch/powerpc/kernel/pci_32.c | 10 ++++
arch/powerpc/kernel/pci_64.c | 8 ++-
arch/powerpc/platforms/82xx/mpc82xx_ads.c | 13 ------
arch/powerpc/platforms/83xx/mpc834x_itx.c | 3 -
arch/powerpc/platforms/83xx/mpc834x_sys.c | 3 -
arch/powerpc/platforms/83xx/mpc83xx.h | 1
arch/powerpc/platforms/83xx/pci.c | 9 ----
arch/powerpc/platforms/85xx/mpc85xx_ads.c | 11 -----
arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | 10 ----
arch/powerpc/platforms/cell/setup.c | 9 ----
arch/powerpc/platforms/chrp/chrp.h | 1
arch/powerpc/platforms/chrp/pci.c | 9 ----
arch/powerpc/platforms/chrp/setup.c | 1
arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | 16 ++-----
arch/powerpc/platforms/maple/maple.h | 2
arch/powerpc/platforms/maple/pci.c | 45 ++++++++--------------
arch/powerpc/platforms/maple/setup.c | 2
arch/powerpc/platforms/pasemi/pasemi.h | 1
arch/powerpc/platforms/pasemi/pci.c | 8 ---
arch/powerpc/platforms/pasemi/setup.c | 1
arch/powerpc/platforms/powermac/pci.c | 35 ++++++-----------
arch/powerpc/platforms/powermac/pmac.h | 2
arch/powerpc/platforms/powermac/setup.c | 2
arch/powerpc/platforms/pseries/pci.c | 35 -----------------
arch/powerpc/platforms/pseries/setup.c | 1
include/asm-powerpc/machdep.h | 2
include/asm-powerpc/ppc-pci.h | 1
27 files changed, 58 insertions(+), 183 deletions(-)
Index: linux-cell/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/pci_32.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/kernel/pci_32.c 2006-11-06 15:04:50.000000000 +1100
@@ -12,6 +12,7 @@
#include <linux/errno.h>
#include <linux/bootmem.h>
#include <linux/irq.h>
+#include <linux/list.h>
#include <asm/processor.h>
#include <asm/io.h>
@@ -1338,6 +1339,7 @@ void __init pcibios_fixup_bus(struct pci
struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
unsigned long io_offset;
struct resource *res;
+ struct pci_dev *dev;
int i;
io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
@@ -1390,8 +1392,16 @@ void __init pcibios_fixup_bus(struct pci
}
}
+ /* Platform specific bus fixups */
if (ppc_md.pcibios_fixup_bus)
ppc_md.pcibios_fixup_bus(bus);
+
+ /* Read default IRQs and fixup if necessary */
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ pci_read_irq_line(dev);
+ if (ppc_md.pci_irq_fixup)
+ ppc_md.pci_irq_fixup(dev);
+ }
}
char __init *pcibios_setup(char *str)
Index: linux-cell/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/pci_64.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/kernel/pci_64.c 2006-11-06 15:02:21.000000000 +1100
@@ -1223,8 +1223,12 @@ static void __devinit do_bus_setup(struc
list_for_each_entry(dev, &bus->devices, bus_list)
ppc_md.iommu_dev_setup(dev);
- if (ppc_md.irq_bus_setup)
- ppc_md.irq_bus_setup(bus);
+ /* Read default IRQs and fixup if necessary */
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ pci_read_irq_line(dev);
+ if (ppc_md.pci_irq_fixup)
+ ppc_md.pci_irq_fixup(dev);
+ }
}
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
Index: linux-cell/arch/powerpc/platforms/pseries/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pseries/pci.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/pseries/pci.c 2006-11-06 15:02:21.000000000 +1100
@@ -29,8 +29,6 @@
#include <asm/prom.h>
#include <asm/ppc-pci.h>
-static int __devinitdata s7a_workaround = -1;
-
#if 0
void pcibios_name_device(struct pci_dev *dev)
{
@@ -57,39 +55,6 @@ void pcibios_name_device(struct pci_dev
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
#endif
-static void __devinit check_s7a(void)
-{
- struct device_node *root;
- const char *model;
-
- s7a_workaround = 0;
- root = of_find_node_by_path("/");
- if (root) {
- model = get_property(root, "model", NULL);
- if (model && !strcmp(model, "IBM,7013-S7A"))
- s7a_workaround = 1;
- of_node_put(root);
- }
-}
-
-void __devinit pSeries_irq_bus_setup(struct pci_bus *bus)
-{
- struct pci_dev *dev;
-
- if (s7a_workaround < 0)
- check_s7a();
- list_for_each_entry(dev, &bus->devices, bus_list) {
- pci_read_irq_line(dev);
- if (s7a_workaround) {
- if (dev->irq > 16) {
- dev->irq -= 3;
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
- dev->irq);
- }
- }
- }
-}
-
static void __init pSeries_request_regions(void)
{
if (!isa_io_base)
Index: linux-cell/arch/powerpc/platforms/pseries/setup.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pseries/setup.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/pseries/setup.c 2006-11-06 15:02:21.000000000 +1100
@@ -553,7 +553,6 @@ define_machine(pseries) {
.log_error = pSeries_log_error,
.pcibios_fixup = pSeries_final_fixup,
.pci_probe_mode = pSeries_pci_probe_mode,
- .irq_bus_setup = pSeries_irq_bus_setup,
.restart = rtas_restart,
.power_off = rtas_power_off,
.halt = rtas_halt,
Index: linux-cell/include/asm-powerpc/machdep.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/machdep.h 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/include/asm-powerpc/machdep.h 2006-11-06 15:02:21.000000000 +1100
@@ -86,7 +86,6 @@ struct machdep_calls {
void (*tce_flush)(struct iommu_table *tbl);
void (*iommu_dev_setup)(struct pci_dev *dev);
void (*iommu_bus_setup)(struct pci_bus *bus);
- void (*irq_bus_setup)(struct pci_bus *bus);
#endif /* CONFIG_PPC64 */
int (*probe)(void);
@@ -106,6 +105,7 @@ struct machdep_calls {
/* Called after scanning the bus, before allocating resources */
void (*pcibios_fixup)(void);
int (*pci_probe_mode)(struct pci_bus *);
+ void (*pci_irq_fixup)(struct pci_dev *dev);
void (*restart)(char *cmd);
void (*power_off)(void);
Index: linux-cell/include/asm-powerpc/ppc-pci.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/ppc-pci.h 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/include/asm-powerpc/ppc-pci.h 2006-11-06 15:02:21.000000000 +1100
@@ -47,7 +47,6 @@ unsigned long get_phb_buid (struct devic
/* From pSeries_pci.h */
extern void pSeries_final_fixup(void);
-extern void pSeries_irq_bus_setup(struct pci_bus *bus);
extern unsigned long pci_probe_only;
Index: linux-cell/arch/powerpc/platforms/cell/setup.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/cell/setup.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/cell/setup.c 2006-11-06 15:02:21.000000000 +1100
@@ -80,14 +80,6 @@ static void cell_progress(char *s, unsig
printk("*** %04x : %s\n", hex, s ? s : "");
}
-static void __init cell_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- for_each_pci_dev(dev)
- pci_read_irq_line(dev);
-}
-
static void __init cell_init_irq(void)
{
iic_init_IRQ();
@@ -180,7 +172,6 @@ define_machine(cell) {
.check_legacy_ioport = cell_check_legacy_ioport,
.progress = cell_progress,
.init_IRQ = cell_init_irq,
- .pcibios_fixup = cell_pcibios_fixup,
#ifdef CONFIG_KEXEC
.machine_kexec = default_machine_kexec,
.machine_kexec_prepare = default_machine_kexec_prepare,
Index: linux-cell/arch/powerpc/platforms/maple/maple.h
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/maple/maple.h 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/maple/maple.h 2006-11-06 15:02:21.000000000 +1100
@@ -8,5 +8,5 @@ extern void maple_get_rtc_time(struct rt
extern unsigned long maple_get_boot_time(void);
extern void maple_calibrate_decr(void);
extern void maple_pci_init(void);
-extern void maple_pcibios_fixup(void);
+extern void maple_pci_irq_fixup(struct pci_dev *dev);
extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
Index: linux-cell/arch/powerpc/platforms/maple/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/maple/pci.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/maple/pci.c 2006-11-06 15:02:21.000000000 +1100
@@ -502,38 +502,29 @@ static int __init add_bridge(struct devi
}
-void __init maple_pcibios_fixup(void)
+void __devinit maple_pci_irq_fixup(struct pci_dev *dev)
{
- struct pci_dev *dev = NULL;
+ DBG(" -> maple_pci_irq_fixup\n");
- DBG(" -> maple_pcibios_fixup\n");
-
- for_each_pci_dev(dev) {
- /* Fixup IRQ for PCIe host */
- if (u4_pcie != NULL && dev->bus->number == 0 &&
- pci_bus_to_host(dev->bus) == u4_pcie) {
- printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n");
- dev->irq = irq_create_mapping(NULL, 1);
- if (dev->irq != NO_IRQ)
- set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
- continue;
- }
-
- /* Hide AMD8111 IDE interrupt when in legacy mode so
- * the driver calls pci_get_legacy_ide_irq()
- */
- if (dev->vendor == PCI_VENDOR_ID_AMD &&
- dev->device == PCI_DEVICE_ID_AMD_8111_IDE &&
- (dev->class & 5) != 5) {
- dev->irq = NO_IRQ;
- continue;
- }
+ /* Fixup IRQ for PCIe host */
+ if (u4_pcie != NULL && dev->bus->number == 0 &&
+ pci_bus_to_host(dev->bus) == u4_pcie) {
+ printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n");
+ dev->irq = irq_create_mapping(NULL, 1);
+ if (dev->irq != NO_IRQ)
+ set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
+ }
- /* For all others, map the interrupt from the device-tree */
- pci_read_irq_line(dev);
+ /* Hide AMD8111 IDE interrupt when in legacy mode so
+ * the driver calls pci_get_legacy_ide_irq()
+ */
+ if (dev->vendor == PCI_VENDOR_ID_AMD &&
+ dev->device == PCI_DEVICE_ID_AMD_8111_IDE &&
+ (dev->class & 5) != 5) {
+ dev->irq = NO_IRQ;
}
- DBG(" <- maple_pcibios_fixup\n");
+ DBG(" <- maple_pci_irq_fixup\n");
}
static void __init maple_fixup_phb_resources(void)
Index: linux-cell/arch/powerpc/platforms/maple/setup.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/maple/setup.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/maple/setup.c 2006-11-06 15:02:21.000000000 +1100
@@ -312,7 +312,7 @@ define_machine(maple_md) {
.setup_arch = maple_setup_arch,
.init_early = maple_init_early,
.init_IRQ = maple_init_IRQ,
- .pcibios_fixup = maple_pcibios_fixup,
+ .pci_irq_fixup = maple_pci_irq_fixup,
.pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq,
.restart = maple_restart,
.power_off = maple_power_off,
Index: linux-cell/arch/powerpc/platforms/powermac/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/powermac/pci.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/powermac/pci.c 2006-11-06 15:02:21.000000000 +1100
@@ -985,30 +985,23 @@ static int __init add_bridge(struct devi
return 0;
}
-void __init pmac_pcibios_fixup(void)
+void __devinit pmac_pci_irq_fixup(struct pci_dev *dev)
{
- struct pci_dev* dev = NULL;
-
- for_each_pci_dev(dev) {
- /* Read interrupt from the device-tree */
- pci_read_irq_line(dev);
-
#ifdef CONFIG_PPC32
- /* Fixup interrupt for the modem/ethernet combo controller.
- * on machines with a second ohare chip.
- * The number in the device tree (27) is bogus (correct for
- * the ethernet-only board but not the combo ethernet/modem
- * board). The real interrupt is 28 on the second controller
- * -> 28+32 = 60.
- */
- if (has_second_ohare &&
- dev->vendor == PCI_VENDOR_ID_DEC &&
- dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) {
- dev->irq = irq_create_mapping(NULL, 60);
- set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
- }
-#endif /* CONFIG_PPC32 */
+ /* Fixup interrupt for the modem/ethernet combo controller.
+ * on machines with a second ohare chip.
+ * The number in the device tree (27) is bogus (correct for
+ * the ethernet-only board but not the combo ethernet/modem
+ * board). The real interrupt is 28 on the second controller
+ * -> 28+32 = 60.
+ */
+ if (has_second_ohare &&
+ dev->vendor == PCI_VENDOR_ID_DEC &&
+ dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) {
+ dev->irq = irq_create_mapping(NULL, 60);
+ set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
}
+#endif /* CONFIG_PPC32 */
}
#ifdef CONFIG_PPC64
Index: linux-cell/arch/powerpc/platforms/powermac/pmac.h
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/powermac/pmac.h 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/powermac/pmac.h 2006-11-06 15:02:21.000000000 +1100
@@ -20,7 +20,7 @@ extern void pmac_get_rtc_time(struct rtc
extern int pmac_set_rtc_time(struct rtc_time *);
extern void pmac_read_rtc_time(void);
extern void pmac_calibrate_decr(void);
-extern void pmac_pcibios_fixup(void);
+extern void pmac_pci_irq_fixup(struct pci_dev *);
extern void pmac_pci_init(void);
extern unsigned long pmac_ide_get_base(int index);
extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
Index: linux-cell/arch/powerpc/platforms/powermac/setup.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/powermac/setup.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/powermac/setup.c 2006-11-06 15:02:21.000000000 +1100
@@ -727,7 +727,7 @@ define_machine(powermac) {
.show_cpuinfo = pmac_show_cpuinfo,
.init_IRQ = pmac_pic_init,
.get_irq = NULL, /* changed later */
- .pcibios_fixup = pmac_pcibios_fixup,
+ .pci_irq_fixup = pmac_pci_irq_fixup,
.restart = pmac_restart,
.power_off = pmac_power_off,
.halt = pmac_halt,
Index: linux-cell/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c 2006-11-06 15:02:21.000000000 +1100
@@ -89,7 +89,7 @@ u8 find_slot_by_devfn(unsigned int *inte
/*
* Scans the interrupt map for pci device
*/
-void mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
+void __devinit mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
{
struct pci_controller *hose;
struct device_node *node;
@@ -117,19 +117,13 @@ void mpc7448_hpc2_fixup_irq(struct pci_d
pin = 1;
pin--;
dev->irq = interrupt[slot*4*7 + pin*7 + 5];
+
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+
DBG("TSI_PCI: dev->irq = 0x%x\n", dev->irq);
}
/* temporary pci irq map fixup*/
-void __init mpc7448_hpc2_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
- for_each_pci_dev(dev) {
- mpc7448_hpc2_fixup_irq(dev);
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
- }
-}
-
static void __init mpc7448_hpc2_setup_arch(void)
{
struct device_node *cpu;
@@ -300,7 +294,7 @@ define_machine(mpc7448_hpc2){
.init_IRQ = mpc7448_hpc2_init_IRQ,
.show_cpuinfo = mpc7448_hpc2_show_cpuinfo,
.get_irq = mpic_get_irq,
- .pcibios_fixup = mpc7448_hpc2_pcibios_fixup,
+ .pci_irq_fixup = mpc7448_hpc2_fixup_irq,
.restart = mpc7448_hpc2_restart,
.calibrate_decr = generic_calibrate_decr,
.machine_check_exception= mpc7448_machine_check_exception,
Index: linux-cell/arch/powerpc/platforms/pasemi/pasemi.h
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pasemi/pasemi.h 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/pasemi/pasemi.h 2006-11-06 15:02:21.000000000 +1100
@@ -3,6 +3,5 @@
extern unsigned long pas_get_boot_time(void);
extern void pas_pci_init(void);
-extern void pas_pcibios_fixup(void);
#endif /* _PASEMI_PASEMI_H */
Index: linux-cell/arch/powerpc/platforms/pasemi/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pasemi/pci.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/pasemi/pci.c 2006-11-06 15:02:21.000000000 +1100
@@ -148,14 +148,6 @@ static int __init add_bridge(struct devi
}
-void __init pas_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- for_each_pci_dev(dev)
- pci_read_irq_line(dev);
-}
-
static void __init pas_fixup_phb_resources(void)
{
struct pci_controller *hose, *tmp;
Index: linux-cell/arch/powerpc/platforms/pasemi/setup.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pasemi/setup.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/pasemi/setup.c 2006-11-06 15:02:21.000000000 +1100
@@ -176,7 +176,6 @@ define_machine(pas) {
.init_early = pas_init_early,
.init_IRQ = pas_init_IRQ,
.get_irq = mpic_get_irq,
- .pcibios_fixup = pas_pcibios_fixup,
.restart = pas_restart,
.power_off = pas_power_off,
.halt = pas_halt,
Index: linux-cell/arch/powerpc/platforms/82xx/mpc82xx_ads.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/82xx/mpc82xx_ads.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/82xx/mpc82xx_ads.c 2006-11-06 15:02:21.000000000 +1100
@@ -515,16 +515,6 @@ static int m82xx_pci_exclude_device(u_ch
return PCIBIOS_SUCCESSFUL;
}
-static void
-__init mpc82xx_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- for_each_pci_dev(dev) {
- pci_read_irq_line(dev);
- }
-}
-
void __init add_bridge(struct device_node *np)
{
int len;
@@ -597,9 +587,6 @@ static void __init mpc82xx_ads_setup_arc
add_bridge(np);
of_node_put(np);
- ppc_md.pci_map_irq = NULL;
- ppc_md.pcibios_fixup = mpc82xx_pcibios_fixup;
- ppc_md.pcibios_fixup_bus = NULL;
#endif
#ifdef CONFIG_ROOT_NFS
Index: linux-cell/arch/powerpc/platforms/83xx/mpc834x_itx.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/83xx/mpc834x_itx.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/83xx/mpc834x_itx.c 2006-11-06 15:02:21.000000000 +1100
@@ -122,7 +122,4 @@ define_machine(mpc834x_itx) {
.time_init = mpc83xx_time_init,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
-#ifdef CONFIG_PCI
- .pcibios_fixup = mpc83xx_pcibios_fixup,
-#endif
};
Index: linux-cell/arch/powerpc/platforms/83xx/mpc834x_sys.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/83xx/mpc834x_sys.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/83xx/mpc834x_sys.c 2006-11-06 15:02:21.000000000 +1100
@@ -137,7 +137,4 @@ define_machine(mpc834x_sys) {
.time_init = mpc83xx_time_init,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
-#ifdef CONFIG_PCI
- .pcibios_fixup = mpc83xx_pcibios_fixup,
-#endif
};
Index: linux-cell/arch/powerpc/platforms/83xx/mpc83xx.h
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/83xx/mpc83xx.h 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/83xx/mpc83xx.h 2006-11-06 15:02:21.000000000 +1100
@@ -11,7 +11,6 @@
extern int add_bridge(struct device_node *dev);
extern int mpc83xx_exclude_device(u_char bus, u_char devfn);
-extern void mpc83xx_pcibios_fixup(void);
extern void mpc83xx_restart(char *cmd);
extern long mpc83xx_time_init(void);
Index: linux-cell/arch/powerpc/platforms/83xx/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/83xx/pci.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/83xx/pci.c 2006-11-06 15:02:21.000000000 +1100
@@ -45,15 +45,6 @@ int mpc83xx_exclude_device(u_char bus, u
return PCIBIOS_SUCCESSFUL;
}
-void __init mpc83xx_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- /* map all the PCI irqs */
- for_each_pci_dev(dev)
- pci_read_irq_line(dev);
-}
-
int __init add_bridge(struct device_node *dev)
{
int len;
Index: linux-cell/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c 2006-11-06 15:02:21.000000000 +1100
@@ -398,15 +398,6 @@ mpc86xx_hpcn_show_cpuinfo(struct seq_fil
}
-void __init mpc86xx_hpcn_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- for_each_pci_dev(dev)
- pci_read_irq_line(dev);
-}
-
-
/*
* Called very early, device-tree isn't unflattened
*/
@@ -461,7 +452,6 @@ define_machine(mpc86xx_hpcn) {
.setup_arch = mpc86xx_hpcn_setup_arch,
.init_IRQ = mpc86xx_hpcn_init_irq,
.show_cpuinfo = mpc86xx_hpcn_show_cpuinfo,
- .pcibios_fixup = mpc86xx_hpcn_pcibios_fixup,
.get_irq = mpic_get_irq,
.restart = mpc86xx_restart,
.time_init = mpc86xx_time_init,
Index: linux-cell/arch/powerpc/platforms/chrp/chrp.h
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/chrp/chrp.h 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/chrp/chrp.h 2006-11-06 15:02:21.000000000 +1100
@@ -9,4 +9,3 @@ extern long chrp_time_init(void);
extern void chrp_find_bridges(void);
extern void chrp_event_scan(unsigned long);
-extern void chrp_pcibios_fixup(void);
Index: linux-cell/arch/powerpc/platforms/chrp/setup.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/chrp/setup.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/chrp/setup.c 2006-11-06 15:02:21.000000000 +1100
@@ -600,7 +600,6 @@ define_machine(chrp) {
.init = chrp_init2,
.show_cpuinfo = chrp_show_cpuinfo,
.init_IRQ = chrp_init_IRQ,
- .pcibios_fixup = chrp_pcibios_fixup,
.restart = rtas_restart,
.power_off = rtas_power_off,
.halt = rtas_halt,
Index: linux-cell/arch/powerpc/platforms/85xx/mpc85xx_ads.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/85xx/mpc85xx_ads.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/85xx/mpc85xx_ads.c 2006-11-06 15:02:21.000000000 +1100
@@ -53,15 +53,6 @@ mpc85xx_exclude_device(u_char bus, u_cha
else
return PCIBIOS_SUCCESSFUL;
}
-
-void __init
-mpc85xx_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- for_each_pci_dev(dev)
- pci_read_irq_line(dev);
-}
#endif /* CONFIG_PCI */
#ifdef CONFIG_CPM2
@@ -253,8 +244,6 @@ static void __init mpc85xx_ads_setup_arc
#ifdef CONFIG_PCI
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
add_bridge(np);
-
- ppc_md.pcibios_fixup = mpc85xx_pcibios_fixup;
ppc_md.pci_exclude_device = mpc85xx_exclude_device;
#endif
Index: linux-cell/arch/powerpc/platforms/chrp/pci.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/chrp/pci.c 2006-11-06 15:02:16.000000000 +1100
+++ linux-cell/arch/powerpc/platforms/chrp/pci.c 2006-11-06 15:02:21.000000000 +1100
@@ -156,15 +156,6 @@ hydra_init(void)
return 1;
}
-void __init
-chrp_pcibios_fixup(void)
-{
- struct pci_dev *dev = NULL;
-
- for_each_pci_dev(dev)
- pci_read_irq_line(dev);
-}
-
#define PRG_CL_RESET_VALID 0x00010000
static void __init
^ permalink raw reply
* [PATCH 4/27] arch provides generic iomap missing accessors
From: Benjamin Herrenschmidt @ 2006-11-06 7:05 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1162796738.274582.277491064706.qpush@grosgo>
From: Linus Torvalds <torvalds@osdl.org>
Allow architectures to provide their own implementation of the big endian MMIO
accessors and "repeat" MMIO accessors for use by the generic iomap.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
More-or-less-tested-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
lib/iomap.c | 32 ++++++++++++++++++++++++++++----
1 file changed, 28 insertions(+), 4 deletions(-)
Index: linux-cell/lib/iomap.c
===================================================================
--- linux-cell.orig/lib/iomap.c 2006-11-05 16:19:32.000000000 +1100
+++ linux-cell/lib/iomap.c 2006-11-05 16:19:40.000000000 +1100
@@ -50,6 +50,16 @@
} \
} while (0)
+#ifndef pio_read16be
+#define pio_read16be(port) swab16(inw(port))
+#define pio_read32be(port) swab32(inl(port))
+#endif
+
+#ifndef mmio_read16be
+#define mmio_read16be(addr) be16_to_cpu(__raw_readw(addr))
+#define mmio_read32be(addr) be32_to_cpu(__raw_readl(addr))
+#endif
+
unsigned int fastcall ioread8(void __iomem *addr)
{
IO_COND(addr, return inb(port), return readb(addr));
@@ -60,7 +70,7 @@
}
unsigned int fastcall ioread16be(void __iomem *addr)
{
- IO_COND(addr, return inw(port), return be16_to_cpu(__raw_readw(addr)));
+ IO_COND(addr, return pio_read16be(port), return mmio_read16be(addr));
}
unsigned int fastcall ioread32(void __iomem *addr)
{
@@ -68,7 +78,7 @@
}
unsigned int fastcall ioread32be(void __iomem *addr)
{
- IO_COND(addr, return inl(port), return be32_to_cpu(__raw_readl(addr)));
+ IO_COND(addr, return pio_read32be(port), return mmio_read32be(addr));
}
EXPORT_SYMBOL(ioread8);
EXPORT_SYMBOL(ioread16);
@@ -76,6 +86,16 @@
EXPORT_SYMBOL(ioread32);
EXPORT_SYMBOL(ioread32be);
+#ifndef pio_write16be
+#define pio_write16be(val,port) outw(swab16(val),port)
+#define pio_write32be(val,port) outl(swab32(val),port)
+#endif
+
+#ifndef mmio_write16be
+#define mmio_write16be(val,port) __raw_writew(be16_to_cpu(val),port)
+#define mmio_write32be(val,port) __raw_writel(be32_to_cpu(val),port)
+#endif
+
void fastcall iowrite8(u8 val, void __iomem *addr)
{
IO_COND(addr, outb(val,port), writeb(val, addr));
@@ -86,7 +106,7 @@
}
void fastcall iowrite16be(u16 val, void __iomem *addr)
{
- IO_COND(addr, outw(val,port), __raw_writew(cpu_to_be16(val), addr));
+ IO_COND(addr, pio_write16be(val,port), mmio_write16be(val, addr));
}
void fastcall iowrite32(u32 val, void __iomem *addr)
{
@@ -94,7 +114,7 @@
}
void fastcall iowrite32be(u32 val, void __iomem *addr)
{
- IO_COND(addr, outl(val,port), __raw_writel(cpu_to_be32(val), addr));
+ IO_COND(addr, pio_write32be(val,port), mmio_write32be(val, addr));
}
EXPORT_SYMBOL(iowrite8);
EXPORT_SYMBOL(iowrite16);
@@ -108,6 +128,7 @@
* convert to CPU byte order. We write in "IO byte
* order" (we also don't have IO barriers).
*/
+#ifndef mmio_insb
static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
{
while (--count >= 0) {
@@ -132,7 +153,9 @@
dst++;
}
}
+#endif
+#ifndef mmio_outsb
static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
{
while (--count >= 0) {
@@ -154,6 +177,7 @@
src++;
}
}
+#endif
void fastcall ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
{
^ permalink raw reply
* [PATCH 3/27] Driver core: add notification of bus events
From: Benjamin Herrenschmidt @ 2006-11-06 7:05 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1162796738.274582.277491064706.qpush@grosgo>
I finally did as you suggested and added the notifier to the struct
bus_type itself. There are still problems to be expected is something
attaches to a bus type where the code can hook in different struct
device sub-classes (which is imho a big bogosity but I won't even try to
argue that case now) but it will solve nicely a number of issues I've
had so far.
That also means that clients interested in registering for such
notifications have to do it before devices are added and after bus types
are registered. Fortunately, most bus types that matter for the various
usage scenarios I have in mind are registerd at postcore_initcall time,
which means I have a really nice spot at arch_initcall time to add my
notifiers.
There are 4 notifications provided. Device being added (before hooked to
the bus) and removed (failure of previous case or after being unhooked
from the bus), along with driver being bound to a device and about to be
unbound.
The usage I have for these are:
- The 2 first ones are used to maintain a struct device_ext that is
hooked to struct device.firmware_data. This structure contains for now a
pointer to the Open Firmware node related to the device (if any), the
NUMA node ID (for quick access to it) and the DMA operations pointers &
iommu table instance for DMA to/from this device. For bus types I own
(like IBM VIO or EBUS), I just maintain that structure directly from the
bus code when creating the devices. But for bus types managed by generic
code like PCI or platform (actually, of_platform which is a variation of
platform linked to Open Firmware device-tree), I need this notifier.
- The other two ones have a completely different usage scenario. I have
cases where multiple devices and their drivers depend on each other. For
example, the IBM EMAC network driver needs to attach to a MAL DMA engine
which is a separate device, and a PHY interface which is also a separate
device. They are all of_platform_device's (well, about to be with my
upcoming patches) but there is no say in what precise order the core
will "probe" them and instanciate the various modules. The solution I
found for that is to have the drivers for emac to use multithread_probe,
and wait for a driver to be bound to the target MAL and PHY control
devices (the device-tree contains reference to the MAL and PHY interface
nodes, which I can then match to of_platform_devices). Right now, I've
been polling, but with that notifier, I can more cleanly wait (with a
timeout of course).
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
This patch is already in Greg KH tree under the name
driver-core-add-notification-of-bus-events.patch
drivers/base/bus.c | 15 +++++++++++++++
drivers/base/core.c | 12 ++++++++++++
drivers/base/dd.c | 10 ++++++++++
include/linux/device.h | 25 ++++++++++++++++++++++++-
4 files changed, 61 insertions(+), 1 deletion(-)
Index: linux-cell/drivers/base/core.c
===================================================================
--- linux-cell.orig/drivers/base/core.c 2006-11-02 13:20:21.000000000 +1100
+++ linux-cell/drivers/base/core.c 2006-11-02 13:20:24.000000000 +1100
@@ -17,6 +17,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/kdev_t.h>
+#include <linux/notifier.h>
#include <asm/semaphore.h>
@@ -428,6 +429,11 @@ int device_add(struct device *dev)
if (platform_notify)
platform_notify(dev);
+ /* notify clients of device entry (new way) */
+ if (dev->bus)
+ blocking_notifier_call_chain(&dev->bus->bus_notifier,
+ BUS_NOTIFY_ADD_DEVICE, dev);
+
dev->uevent_attr.attr.name = "uevent";
dev->uevent_attr.attr.mode = S_IWUSR;
if (dev->driver)
@@ -504,6 +510,9 @@ int device_add(struct device *dev)
BusError:
device_pm_remove(dev);
PMError:
+ if (dev->bus)
+ blocking_notifier_call_chain(&dev->bus->bus_notifier,
+ BUS_NOTIFY_DEL_DEVICE, dev);
device_remove_groups(dev);
GroupError:
device_remove_attrs(dev);
@@ -622,6 +631,9 @@ void device_del(struct device * dev)
*/
if (platform_notify_remove)
platform_notify_remove(dev);
+ if (dev->bus)
+ blocking_notifier_call_chain(&dev->bus->bus_notifier,
+ BUS_NOTIFY_DEL_DEVICE, dev);
device_pm_remove(dev);
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj);
Index: linux-cell/include/linux/device.h
===================================================================
--- linux-cell.orig/include/linux/device.h 2006-10-25 12:50:17.000000000 +1000
+++ linux-cell/include/linux/device.h 2006-11-02 13:20:24.000000000 +1100
@@ -42,6 +42,8 @@ struct bus_type {
struct klist klist_devices;
struct klist klist_drivers;
+ struct blocking_notifier_head bus_notifier;
+
struct bus_attribute * bus_attrs;
struct device_attribute * dev_attrs;
struct driver_attribute * drv_attrs;
@@ -75,6 +77,28 @@ int __must_check bus_for_each_drv(struct
struct device_driver *start, void *data,
int (*fn)(struct device_driver *, void *));
+/* Bus notifiers: Get notified of addition/removal of devices
+ * and binding/unbinding of drivers to devices.
+ * In the long run, it should be a replacement for the platform
+ * notify hooks.
+ */
+struct notifier_block;
+
+extern int register_bus_notifier(struct bus_type *bus,
+ struct notifier_block *nb);
+extern int unregister_bus_notifier(struct bus_type *bus,
+ struct notifier_block *nb);
+
+/* All 4 notifers below get called with the target struct device *
+ * as an argument. Note that those functions are likely to be called
+ * with the device semaphore held in the core, so be careful.
+ */
+#define BUS_NOTIFY_ADD_DEVICE 0x00000001 /* device added */
+#define BUS_NOTIFY_DEL_DEVICE 0x00000002 /* device removed */
+#define BUS_NOTIFY_BOUND_DRIVER 0x00000003 /* driver bound to device */
+#define BUS_NOTIFY_UNBIND_DRIVER 0x00000004 /* driver about to be
+ unbound */
+
/* driverfs interface for exporting bus attributes */
struct bus_attribute {
@@ -427,7 +451,6 @@ extern int (*platform_notify)(struct dev
extern int (*platform_notify_remove)(struct device * dev);
-
/**
* get_device - atomically increment the reference count for the device.
*
Index: linux-cell/drivers/base/bus.c
===================================================================
--- linux-cell.orig/drivers/base/bus.c 2006-10-23 14:41:37.000000000 +1000
+++ linux-cell/drivers/base/bus.c 2006-11-02 13:20:24.000000000 +1100
@@ -724,6 +724,8 @@ int bus_register(struct bus_type * bus)
{
int retval;
+ BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier);
+
retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name);
if (retval)
goto out;
@@ -782,6 +784,16 @@ void bus_unregister(struct bus_type * bu
subsystem_unregister(&bus->subsys);
}
+int register_bus_notifier(struct bus_type *bus, struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&bus->bus_notifier, nb);
+}
+
+int unregister_bus_notifier(struct bus_type *bus, struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&bus->bus_notifier, nb);
+}
+
int __init buses_init(void)
{
return subsystem_register(&bus_subsys);
@@ -798,3 +810,6 @@ EXPORT_SYMBOL_GPL(bus_rescan_devices);
EXPORT_SYMBOL_GPL(bus_create_file);
EXPORT_SYMBOL_GPL(bus_remove_file);
+
+EXPORT_SYMBOL_GPL(register_bus_notifier);
+EXPORT_SYMBOL_GPL(unregister_bus_notifier);
Index: linux-cell/drivers/base/dd.c
===================================================================
--- linux-cell.orig/drivers/base/dd.c 2006-10-30 08:00:39.000000000 +1100
+++ linux-cell/drivers/base/dd.c 2006-11-02 13:20:24.000000000 +1100
@@ -52,6 +52,11 @@ int device_bind_driver(struct device *de
pr_debug("bound device '%s' to driver '%s'\n",
dev->bus_id, dev->driver->name);
+
+ if (dev->bus)
+ blocking_notifier_call_chain(&dev->bus->bus_notifier,
+ BUS_NOTIFY_BOUND_DRIVER, dev);
+
klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj,
kobject_name(&dev->kobj));
@@ -288,6 +293,11 @@ static void __device_release_driver(stru
sysfs_remove_link(&dev->kobj, "driver");
klist_remove(&dev->knode_driver);
+ if (dev->bus)
+ blocking_notifier_call_chain(&dev->bus->bus_notifier,
+ BUS_NOTIFY_UNBIND_DRIVER,
+ dev);
+
if (dev->bus && dev->bus->remove)
dev->bus->remove(dev);
else if (drv->remove)
^ permalink raw reply
* [PATCH 2/27] Call platform_notify_remove later
From: Benjamin Herrenschmidt @ 2006-11-06 7:05 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1162796738.274582.277491064706.qpush@grosgo>
Move the call to platform_notify_remove() to after the call to
bus_remove_device(), where it belongs. It's bogus to notify the platform
of removal while drivers are still attached to the device and possibly
still operating since the platform might use this callback to tear down
some resources used by the driver (ACPI bits, iommu table, ...)
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: "Brown, Len" <len.brown@intel.com>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---
This patch is already in -mm under the name
call-platform_notify_remove-later.patch
drivers/base/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Index: linux-cell/drivers/base/core.c
===================================================================
--- linux-cell.orig/drivers/base/core.c 2006-10-25 13:04:40.000000000 +1000
+++ linux-cell/drivers/base/core.c 2006-10-25 13:04:56.000000000 +1000
@@ -615,12 +615,13 @@ void device_del(struct device * dev)
device_remove_groups(dev);
device_remove_attrs(dev);
+ bus_remove_device(dev);
+
/* Notify the platform of the removal, in case they
* need to do anything...
*/
if (platform_notify_remove)
platform_notify_remove(dev);
- bus_remove_device(dev);
device_pm_remove(dev);
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj);
^ permalink raw reply
* [PATCH 1/27] ibmveth: Remove ibmveth "liobn" field
From: Benjamin Herrenschmidt @ 2006-11-06 7:05 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1162796738.274582.277491064706.qpush@grosgo>
Remove the now unused "liobn" field in ibmveth which also avoids
having insider knowledge of the iommu table in that driver.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Santiago Leon <santil@us.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
Already in Jeff's queue.
drivers/net/ibmveth.c | 4 ----
drivers/net/ibmveth.h | 1 -
2 files changed, 5 deletions(-)
Index: linux-cell/drivers/net/ibmveth.c
===================================================================
--- linux-cell.orig/drivers/net/ibmveth.c 2006-10-23 14:41:38.000000000 +1000
+++ linux-cell/drivers/net/ibmveth.c 2006-10-25 14:12:05.000000000 +1000
@@ -50,7 +50,6 @@
#include <asm/semaphore.h>
#include <asm/hvcall.h>
#include <asm/atomic.h>
-#include <asm/iommu.h>
#include <asm/vio.h>
#include <asm/uaccess.h>
#include <linux/seq_file.h>
@@ -1000,8 +999,6 @@ static int __devinit ibmveth_probe(struc
adapter->mac_addr = 0;
memcpy(&adapter->mac_addr, mac_addr_p, 6);
- adapter->liobn = dev->iommu_table->it_index;
-
netdev->irq = dev->irq;
netdev->open = ibmveth_open;
netdev->poll = ibmveth_poll;
@@ -1115,7 +1112,6 @@ static int ibmveth_seq_show(struct seq_f
seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version);
seq_printf(seq, "Unit Address: 0x%x\n", adapter->vdev->unit_address);
- seq_printf(seq, "LIOBN: 0x%lx\n", adapter->liobn);
seq_printf(seq, "Current MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
current_mac[0], current_mac[1], current_mac[2],
current_mac[3], current_mac[4], current_mac[5]);
Index: linux-cell/drivers/net/ibmveth.h
===================================================================
--- linux-cell.orig/drivers/net/ibmveth.h 2006-10-06 13:48:09.000000000 +1000
+++ linux-cell/drivers/net/ibmveth.h 2006-10-25 14:10:39.000000000 +1000
@@ -118,7 +118,6 @@ struct ibmveth_adapter {
struct net_device_stats stats;
unsigned int mcastFilterSize;
unsigned long mac_addr;
- unsigned long liobn;
void * buffer_list_addr;
void * filter_list_addr;
dma_addr_t buffer_list_dma;
^ permalink raw reply
* [PATCH 0/27] My current serie of patches for 2.6.20 for review
From: Benjamin Herrenschmidt @ 2006-11-06 7:05 UTC (permalink / raw)
To: linuxppc-dev
This is the whole of my current patch set that I intend to merge
as soon as 2.6.20 merge window opens. I'm posting them here for
review, some of them already had a few iterations on the list by
their own, some didn't show up publically at all yet.
Note that the first 4 ones require specific comments:
- powerpc-ibmveth-remove-liobn.diff should already be queued with
Jeff Garzik
- platform-notify-remove-change.diff
- device-notifier.diff should both be already queued with Greg KH
- iomap-arch-accessors.diff was written by Linus but is not merged
yet. He asked me to resend it when needed, so I'll include it with
the other patches when the merge window opens.
This patch set started its life as the support for the new "Axon"
southbridge for cell (which includes such things as MMIO mapped DCR
and 4xx-type devices). However, as things evolved, I ended up doing
a lot more than just the basic support. Among other highlights of
this patch serie are:
- Generic DCR support for both 4xx-type DCRs and MMIO mapped DCR and
MPIC & EMAC changes to work with that
- Souped up of_platform_driver to make it easier to register entire
trees of devices at once, along with PCI host bridge detection support
for 64 bits architectures. Note that some name changes might break
compile of some platforms. I hope to have fixed everything before I
merge but don't forget to tell me if I missed something.
- Completely reworked 64 bits DMA operations
- Possibility to "hook" on PCI MMIO and PCI operations from the platform
code for use by iSeries, Cell and possibly others who have to deal with
weird hypervisor or PCI host bridge erratas. Currently supported only on
64 bits but would be easy to make it work on 32 bits if ever needed.
- Merged 32 and 64 bits io.h. ARCH=powerpc now uses asm-powerpc/io.h
for both. ARCH=ppc still uses the old one in asm-ppc as I really don't
feel like dealing with some of the cruft in there.
- As a consequence of the 2 above, new accessors are available that match
what is done by other architectures: {read,write}{w,l,q}_be for big endian
PCI MMIO accesses, {read,write}s{b,w,l} for MMIO "repeat" operations, and
a significant cleanup of the EEH stuff.
^ permalink raw reply
* Re: [PATCH/RFC] powerpc: Add MPC5200 Interrupt Controller support.
From: Grant Likely @ 2006-11-06 6:55 UTC (permalink / raw)
To: Nicolas DET; +Cc: linuxppc-dev, sl, linuxppc-embedded
In-Reply-To: <454A5952.6090801@bplan-gmbh.de>
I still haven't had the time to get this code working on my board, and
I haven't followed the discussion over the last week very carefully,
but here's my comments anyway. :)
On 11/2/06, Nicolas DET <nd@bplan-gmbh.de> wrote:
> --- a/arch/powerpc/sysdev/mpc52xx_pic.c 1970-01-01 01:00:00.000000000 +0100
> +++ b/arch/powerpc/sysdev/mpc52xx_pic.c 2006-11-02 17:56:10.000000000 +0100
> +static inline void io_be_setbit(u32 __iomem *addr, int bitno)
> +{
> + out_be32(addr, in_be32(addr) | (1 << bitno) );
> +}
> +
> +static inline void io_be_clrbit(u32 __iomem *addr, int bitno)
> +{
> + out_be32(addr, in_be32(addr) & ~(1 << bitno));
> +}
> +
Do these belong somewhere else? In common code somewhere? Does this
have the side effect of looking like an atomic operation to the casual
observer? (That's a coding convention question directed at Ben)
> +static inline struct device_node *find_mpc52xx_picnode(void)
> +{
> + return of_find_compatible_node(NULL, "interrupt-controller",
> + "mpc5200-pic");
> +}
> +
> +static inline struct device_node *find_mpc52xx_sdmanode(void)
> +{
> + return of_find_compatible_node(NULL, "dma-controller",
> + "mpc5200-bestcomm");
> +}
I don't think this is a very good idea from a maintenance perspective.
Effectively, they replace a single line of code with 5 lines (4 for
the static func, 1 where it is called). If in the future they ever
need to be called in more than 1 or 2 places, then this could be
revisited.
> +
> +/*
> + * IRQ[0-3] interrupt irq_chip
> +*/
> +
> +static void mpc52xx_extirq_mask(unsigned int virq)
> +{
> + int irq;
> + int l2irq;
> +
> + irq = irq_map[virq].hwirq;
> + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
L2 offset will always be 0; why not just omit all references to it?
Keeps the code slightly more concise.
> +/*
> + * init (public)
> +*/
> +
> +void __init mpc52xx_init_irq(void)
> +{
> + struct device_node *picnode;
> + int picnode_regsize;
> + u32 picnode_regoffset;
> +
> + struct device_node *sdmanode;
> + int sdmanode_regsize;
> + u32 sdmanode_regoffset;
> +
> + u64 size64;
> + int flags;
> +
> + u32 intr_ctrl;
> +
> + picnode = find_mpc52xx_picnode();
> + sdmanode = find_mpc52xx_sdmanode();
> +
> + if ( (picnode == NULL) || (sdmanode == NULL) )
> + return;
I don't think you should fail silently here.
> +
> + /* Retrieve PIC ressources */
> + picnode_regoffset = (u32) of_get_address(picnode, 0, &size64, &flags);
> + if (picnode_regoffset == 0)
> + return ;
ditto
> +
> + picnode_regoffset = of_translate_address(picnode, (u32 *) picnode_regoffset);
> + picnode_regsize = (int)size64;
> +
> + /* Retrieve SDMA ressources */
> + sdmanode_regoffset = (u32) of_get_address(sdmanode, 0, &size64, &flags);
> + if (sdmanode_regoffset == 0)
> + return ;
ditto
> +
> + sdmanode_regoffset = of_translate_address(sdmanode, (u32 *) sdmanode_regoffset);
> + sdmanode_regsize = (int)size64;
> +
> + /* Remap the necessary zones */
> + intr = ioremap(picnode_regoffset, picnode_regsize);
> + sdma = ioremap(sdmanode_regoffset, sdmanode_regsize);
> +
> + if ((intr == NULL) || (sdma == NULL))
> + panic("Can't ioremap PIC/SDMA register or init_irq !");
> +
> + printk(KERN_INFO "Remapped MPC52xx PIC at 0x%8.8x\n", picnode_regoffset);
> + printk(KERN_INFO "Remapped MPC52xx SDMA at 0x%8.8x\n", sdmanode_regoffset);
> +
> + of_node_put(picnode);
> + of_node_put(sdmanode);
Silent failure cases above will bypass these calls to of_node_put().
> +
> + /* Disable all interrupt sources. */
> + out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */
> + out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */
> + out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */
> + out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */
> + intr_ctrl = in_be32(&intr->ctrl);
> + intr_ctrl &= 0x00ff0000; /* Keeps IRQ[0-3] config */
> + intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */
> + 0x00001000 | /* MEE master external enable */
> + 0x00000000 | /* 0 means disable IRQ 0-3 */
> + 0x00000001; /* CEb route critical normally */
> + out_be32(&intr->ctrl, intr_ctrl);
> +
> + /* Zero a bunch of the priority settings. */
> + out_be32(&intr->per_pri1, 0);
> + out_be32(&intr->per_pri2, 0);
> + out_be32(&intr->per_pri3, 0);
> + out_be32(&intr->main_pri1, 0);
> + out_be32(&intr->main_pri2, 0);
> +
> + /*
> + * As last step, add an irq host to translate the real
> + * hw irq information provided by the ofw to linux virq
> + */
> +
> + mpc52xx_irqhost =
> + irq_alloc_host(IRQ_HOST_MAP_LINEAR, MPC52xx_IRQ_HIGHTESTVIRQ,
> + &mpc52xx_irqhost_ops, -1);
> +
> + if (mpc52xx_irqhost)
> + mpc52xx_irqhost->host_data = picnode;
> +}
> +
> +/*
> + * get_irq (public)
> +*/
> +unsigned int mpc52xx_get_irq(void)
> +{
> + u32 status;
> + int irq = NO_IRQ_IGNORE;
> +
> + status = in_be32(&intr->enc_status);
> + if (status & 0x00000400) { /* critical */
> + irq = (status >> 8) & 0x3;
> + if (irq == 2) /* high priority peripheral */
> + goto peripheral;
> + irq |=
> + (MPC52xx_IRQ_L1_CRIT << MPC52xx_IRQ_L1_OFFSET) &
> + MPC52xx_IRQ_L1_MASK;
> + } else if (status & 0x00200000) { /* main */
> + irq = (status >> 16) & 0x1f;
> + if (irq == 4) /* low priority peripheral */
> + goto peripheral;
> + irq |=
> + (MPC52xx_IRQ_L1_MAIN << MPC52xx_IRQ_L1_OFFSET) &
> + MPC52xx_IRQ_L1_MASK;
> + } else if (status & 0x20000000) { /* peripheral */
> + peripheral:
> + irq = (status >> 24) & 0x1f;
> + if (irq == 0) { /* bestcomm */
> + status = in_be32(&sdma->IntPend);
> + irq = ffs(status) - 1;
> + irq |=
> + (MPC52xx_IRQ_L1_SDMA << MPC52xx_IRQ_L1_OFFSET) &
> + MPC52xx_IRQ_L1_MASK;
> + } else
> + irq |=
> + (MPC52xx_IRQ_L1_PERP << MPC52xx_IRQ_L1_OFFSET) &
> + MPC52xx_IRQ_L1_MASK;
> +
> + }
> +
> + pr_debug("%s: irq=%x. virq=%d\n", __func__, irq,
> + irq_linear_revmap(mpc52xx_irqhost, irq));
> +
> + return irq_linear_revmap(mpc52xx_irqhost, irq);
> +}
> --- a/include/asm-powerpc/mpc52xx.h 1970-01-01 01:00:00.000000000 +0100
> +++ b/include/asm-powerpc/mpc52xx.h 2006-11-02 17:54:37.000000000 +0100
> @@ -0,0 +1,319 @@
> +/*
> + *
> + * Prototypes, etc. for the Freescale MPC52xx embedded cpu chips
> + * May need to be cleaned as the port goes on ...
> + *
> + * Copyright (C) 2004-2005 Sylvain Munaut <tnt@246tNt.com>
> + * Copyright (C) 2003 MontaVista, Software, Inc.
> + *
> + * This file is licensed under the terms of the GNU General Public License
> + * version 2. This program is licensed "as is" without any warranty of any
> + * kind, whether express or implied.
> + */
> +
> +#ifndef __ASM_POWERPC_MPC52xx_H__
> +#define __ASM_POWERPC_MPC52xx_H__
> +
> +#ifndef __ASSEMBLY__
> +#include <asm/types.h>
> +#include <asm/prom.h>
> +
> +#endif /* __ASSEMBLY__ */
> +
> +/* ======================================================================== */
> +/* Main registers/struct addresses */
> +/* ======================================================================== */
> +
> +/* Registers zone offset/size */
> +#define MPC52xx_MMAP_CTL_OFFSET 0x0000
> +#define MPC52xx_MMAP_CTL_SIZE 0x068
> +#define MPC52xx_SDRAM_OFFSET 0x0100
> +#define MPC52xx_SDRAM_SIZE 0x010
> +#define MPC52xx_CDM_OFFSET 0x0200
> +#define MPC52xx_CDM_SIZE 0x038
> +#define MPC52xx_INTR_OFFSET 0x0500
> +#define MPC52xx_INTR_SIZE 0x04c
> +#define MPC52xx_GPTx_OFFSET(x) (0x0600 + ((x)<<4))
> +#define MPC52xx_GPT_SIZE 0x010
> +#define MPC52xx_RTC_OFFSET 0x0800
> +#define MPC52xx_RTC_SIZE 0x024
> +#define MPC52xx_GPIO_OFFSET 0x0b00
> +#define MPC52xx_GPIO_SIZE 0x040
> +#define MPC52xx_GPIO_WKUP_OFFSET 0x0c00
> +#define MPC52xx_GPIO_WKUP_SIZE 0x028
> +#define MPC52xx_PCI_OFFSET 0x0d00
> +#define MPC52xx_PCI_SIZE 0x100
> +#define MPC52xx_SDMA_OFFSET 0x1200
> +#define MPC52xx_SDMA_SIZE 0x100
> +#define MPC52xx_XLB_OFFSET 0x1f00
> +#define MPC52xx_XLB_SIZE 0x100
> +#define MPC52xx_PSCx_OFFSET(x) (((x)!=6)?(0x1e00+((x)<<9)):0x2c00)
> +#define MPC52xx_PSC_SIZE 0x0a0
> +
> +/* SRAM used for SDMA */
> +#define MPC52xx_SRAM_OFFSET 0x8000
> +#define MPC52xx_SRAM_SIZE 0x4000
Register addresses/lengths are being passed by the device tree. I
think they should be taken out of here to remove the temptation for
driver writers to use them.
g.
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply
* Please give your feedback
From: Manjunath AM @ 2006-11-06 6:57 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 497 bytes --]
Hi, am Manjunath AM,
We are using PQ2FADS dev board for our development, I have following
questions, please give your valuable reply
1. I am using toolchain which support u-boot 1.1.1 and i could not get
toolchain that support u-boot 1.1.3 and above in the net as well as in
Freescale site,
Please suggest me where i can download the toolchain to use u-boot1.1.3
Thanks & Regards
MANJUNATH AM
Senior Software Engineer
Emsys
Larsen & Toubro Limited
Mysore-570018
Mobile:9886375926
[-- Attachment #2: Type: text/html, Size: 770 bytes --]
^ permalink raw reply
* Re: [PATCH/RFC] powerpc: Add MPC5200 Interrupt Controller support.
From: Grant Likely @ 2006-11-06 6:28 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, sl, linuxppc-embedded
In-Reply-To: <1162689227.28571.123.camel@localhost.localdomain>
On 11/4/06, Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> On Sun, 2006-11-05 at 01:27 +0100, Sylvain Munaut wrote:
> > with a helper that would do
> > - The find_node
> > - get_address / translate / get_size
> > - ioremap
> >
> > Something like :
> >
> > intr = mpc52xx_find_and_map("mpc52xx-intr");
> > sdma = mpc52xx_find_and_map("mpc52xx-sdma");
>
> Hrm... I don't care that much but I also don't think we need that
> helper. It's not saving much.
While on this topic... if a helper is added, what about it is 52xx
specific? Wouldn't the same code apply to all platforms?
g.
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply
* Re: ppc32 PIO recovery mecanism
From: Olaf Hering @ 2006-11-06 6:25 UTC (permalink / raw)
To: David Woodhouse; +Cc: linuxppc-dev list
In-Reply-To: <1162794242.3415.28.camel@shinybook.infradead.org>
On Mon, Nov 06, David Woodhouse wrote:
> On Mon, 2006-11-06 at 07:11 +0100, Olaf Hering wrote:
> > On Mon, Nov 06, David Woodhouse wrote:
> >
> > > Yes, I think it's still useful because there are some drivers which
> > > aren't update to use check_legacy_ioport() (or whatever other system)
> > > yet.
> >
> > What remaining drivers do you have in mind here?
>
> Did ISAPnP get fixed?
I have to check, only PReP systems have ISA slots.
^ permalink raw reply
* Re: ppc32 PIO recovery mecanism
From: David Woodhouse @ 2006-11-06 6:24 UTC (permalink / raw)
To: Olaf Hering; +Cc: linuxppc-dev list
In-Reply-To: <20061106061148.GA4361@suse.de>
On Mon, 2006-11-06 at 07:11 +0100, Olaf Hering wrote:
> On Mon, Nov 06, David Woodhouse wrote:
>
> > Yes, I think it's still useful because there are some drivers which
> > aren't update to use check_legacy_ioport() (or whatever other system)
> > yet.
>
> What remaining drivers do you have in mind here?
Did ISAPnP get fixed?
--
dwmw2
^ permalink raw reply
* Re: ppc32 PIO recovery mecanism
From: Olaf Hering @ 2006-11-06 6:11 UTC (permalink / raw)
To: David Woodhouse; +Cc: linuxppc-dev list
In-Reply-To: <1162775915.3415.2.camel@shinybook.infradead.org>
On Mon, Nov 06, David Woodhouse wrote:
> Yes, I think it's still useful because there are some drivers which
> aren't update to use check_legacy_ioport() (or whatever other system)
> yet.
What remaining drivers do you have in mind here?
^ permalink raw reply
* Re: Linuxppc-embedded Digest, Vol 27, Issue 25
From: Basavaraju.Rammohan @ 2006-11-06 5:38 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <mailman.3.1162774802.3433.linuxppc-embedded@ozlabs.org>
[-- Attachment #1: Type: text/plain, Size: 144 bytes --]
Hi
this Forum is simply superb... keep on going & thanks a lot
______________________________________________________________________
[-- Attachment #2: Type: text/html, Size: 267 bytes --]
^ permalink raw reply
* Re: fixup_bigphys_addr and ioremap64 question
From: Benjamin Herrenschmidt @ 2006-11-06 4:46 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev list
In-Reply-To: <1162786580.19697.9.camel@crusty.rchland.ibm.com>
> Hm.. that might be ok. I'm hoping to get back to working on something
> soon so I'll be able to tell more later. Maybe Matt knows for sure.
>
> It'll probably break out-of-tree drivers though once the merge happens
> for 4xx. Could we leave ioremap64 around for a bit with a deprecation
> warning?
I'd rather not... I don't really care about out of tree drivers anyway.
Ben.
^ permalink raw reply
* Re: fixup_bigphys_addr and ioremap64 question
From: Josh Boyer @ 2006-11-06 4:16 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list
In-Reply-To: <1162786162.28571.286.camel@localhost.localdomain>
On Mon, 2006-11-06 at 15:09 +1100, Benjamin Herrenschmidt wrote:
> > > So why do we have both ioremap and ioremap64 knowing that the former is
> > > defined to take a phys_addr_t argument ?
> > >
> > > Currently, we have both, with the only difference being that ioremap
> > > calls ioremap64 but also passes the argument through a
> > > fixup_bigphys_addr() function first.
> > >
> > > It took me a while to find it ... it's not defined in generic code but
> > > in platform code (ugh !). In fact, the only version of it we have in
> > > arch/powerpc is in the 85xx support and does:
> >
> > It's in arch/ppc/syslib/44x_common.c and it's used to trap the least
> > significant 32 bits of an address and set the right ERPN for io space on
> > 44x. Something like that might be needed when 44x merges to
> > arch/powerpc.
>
> Well, my point is that since nowadays we have 64 bits struct resource
> and 64 bits phys_addr_t passed to ioremap, do we still need that ? In
> fact, in my upcoming patch merging io.h for 32 and 64 bits in
> asm-powerpc, I've simply removed that hook and ioremap64 :-) I can add
> it back still, but so far, I yet have to be convinced there is still a
> good reason for that hook.
Hm.. that might be ok. I'm hoping to get back to working on something
soon so I'll be able to tell more later. Maybe Matt knows for sure.
It'll probably break out-of-tree drivers though once the merge happens
for 4xx. Could we leave ioremap64 around for a bit with a deprecation
warning?
josh
^ permalink raw reply
* Re: fixup_bigphys_addr and ioremap64 question
From: Benjamin Herrenschmidt @ 2006-11-06 4:09 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev list
In-Reply-To: <1162784661.19697.4.camel@crusty.rchland.ibm.com>
> > So why do we have both ioremap and ioremap64 knowing that the former is
> > defined to take a phys_addr_t argument ?
> >
> > Currently, we have both, with the only difference being that ioremap
> > calls ioremap64 but also passes the argument through a
> > fixup_bigphys_addr() function first.
> >
> > It took me a while to find it ... it's not defined in generic code but
> > in platform code (ugh !). In fact, the only version of it we have in
> > arch/powerpc is in the 85xx support and does:
>
> It's in arch/ppc/syslib/44x_common.c and it's used to trap the least
> significant 32 bits of an address and set the right ERPN for io space on
> 44x. Something like that might be needed when 44x merges to
> arch/powerpc.
Well, my point is that since nowadays we have 64 bits struct resource
and 64 bits phys_addr_t passed to ioremap, do we still need that ? In
fact, in my upcoming patch merging io.h for 32 and 64 bits in
asm-powerpc, I've simply removed that hook and ioremap64 :-) I can add
it back still, but so far, I yet have to be convinced there is still a
good reason for that hook.
Ben.
^ permalink raw reply
* Re: fixup_bigphys_addr and ioremap64 question
From: Josh Boyer @ 2006-11-06 3:44 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list
In-Reply-To: <1162783045.28571.283.camel@localhost.localdomain>
On Mon, 2006-11-06 at 14:17 +1100, Benjamin Herrenschmidt wrote:
> While merging io.h between 32 and 64 bits arch/powerpc, I stumbled upon
> this little gem :-)
>
> So we have these:
>
> - If CONFIG_PHYS_64BIT is not set, nothing special. phys_addr_t is
> defined to be 32 bits.
>
> - If it is set however, we have phys_addr_t defined to be 64 bits in
> asm-ppc/mmu.h.
>
> So why do we have both ioremap and ioremap64 knowing that the former is
> defined to take a phys_addr_t argument ?
>
> Currently, we have both, with the only difference being that ioremap
> calls ioremap64 but also passes the argument through a
> fixup_bigphys_addr() function first.
>
> It took me a while to find it ... it's not defined in generic code but
> in platform code (ugh !). In fact, the only version of it we have in
> arch/powerpc is in the 85xx support and does:
It's in arch/ppc/syslib/44x_common.c and it's used to trap the least
significant 32 bits of an address and set the right ERPN for io space on
44x. Something like that might be needed when 44x merges to
arch/powerpc.
josh
^ permalink raw reply
* fixup_bigphys_addr and ioremap64 question
From: Benjamin Herrenschmidt @ 2006-11-06 3:17 UTC (permalink / raw)
To: linuxppc-dev list
While merging io.h between 32 and 64 bits arch/powerpc, I stumbled upon
this little gem :-)
So we have these:
- If CONFIG_PHYS_64BIT is not set, nothing special. phys_addr_t is
defined to be 32 bits.
- If it is set however, we have phys_addr_t defined to be 64 bits in
asm-ppc/mmu.h.
So why do we have both ioremap and ioremap64 knowing that the former is
defined to take a phys_addr_t argument ?
Currently, we have both, with the only difference being that ioremap
calls ioremap64 but also passes the argument through a
fixup_bigphys_addr() function first.
It took me a while to find it ... it's not defined in generic code but
in platform code (ugh !). In fact, the only version of it we have in
arch/powerpc is in the 85xx support and does:
phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size)
{
return addr;
};
So here's my question: Is it, as I think, some old mecanism that was
useful when ioremap didn't take a phys_addr_t argument and resources
didn't have 64 bits fields and thus we had a way to "remap" IOs from a
32 bits space into a 64 bits space in a platform specific way ?
Now, the big question is: do we still need that ?
If, as I expect, the answer is no, then I'll just remove it. I'll also
remove ioremap64 from arch/powerpc since ioremap can take a 64 bits
value directly.
Now, if the answer is yes, then I'll turn it into a ppc_md. call since
it its current form, it's just broken.
Ben.
^ permalink raw reply
* Re: ppc32 PIO recovery mecanism
From: Benjamin Herrenschmidt @ 2006-11-06 1:20 UTC (permalink / raw)
To: David Woodhouse; +Cc: linuxppc-dev list, Olaf Hering
In-Reply-To: <1162775915.3415.2.camel@shinybook.infradead.org>
On Mon, 2006-11-06 at 09:18 +0800, David Woodhouse wrote:
> On Mon, 2006-11-06 at 11:41 +1100, Benjamin Herrenschmidt wrote:
> > On 32 bits powerpc, we currently have a mechanism where we try to
> > recover from machine checks happening on PIO operations (inb/outb/....).
> > This mecanisms has proven of dubious reliability in the past and it's my
> > understanding that we've pretty fixed all relevant legacy drivers that
> > distro typically load so that they don't muck around when they
> > shouldn't.
> >
> > I'm currently merging 32 and 64 bits io.h and I would really like to
> > just get rid of that stuff, but I'd like your distro point of view
> > first. Is this mechanism still useful at all or not ?
>
> Yes, I think it's still useful because there are some drivers which
> aren't update to use check_legacy_ioport() (or whatever other system)
> yet.
>
> Not many, mind you -- but I'd like to be 100% sure before we drop it.
> Let's start by making it print with KERN_CRIT instead of KERN_DEBUG?
We should rate limit if we do that tho... Some drivers will just totally
flood you.
I'll keep it around for now.
Ben.
^ permalink raw reply
* Re: ppc32 PIO recovery mecanism
From: David Woodhouse @ 2006-11-06 1:18 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, Olaf Hering
In-Reply-To: <1162773695.28571.260.camel@localhost.localdomain>
On Mon, 2006-11-06 at 11:41 +1100, Benjamin Herrenschmidt wrote:
> On 32 bits powerpc, we currently have a mechanism where we try to
> recover from machine checks happening on PIO operations (inb/outb/....).
> This mecanisms has proven of dubious reliability in the past and it's my
> understanding that we've pretty fixed all relevant legacy drivers that
> distro typically load so that they don't muck around when they
> shouldn't.
>
> I'm currently merging 32 and 64 bits io.h and I would really like to
> just get rid of that stuff, but I'd like your distro point of view
> first. Is this mechanism still useful at all or not ?
Yes, I think it's still useful because there are some drivers which
aren't update to use check_legacy_ioport() (or whatever other system)
yet.
Not many, mind you -- but I'd like to be 100% sure before we drop it.
Let's start by making it print with KERN_CRIT instead of KERN_DEBUG?
--
dwmw2
^ permalink raw reply
* Re: [PATCH/RFC] Hookable IO operations #3
From: Benjamin Herrenschmidt @ 2006-11-06 1:01 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev
In-Reply-To: <200611060038.07117.arnd@arndb.de>
> Why do you write stuff like
>
> if (pointer != NULL) ?
>
> It looks really pointless, since the existence of the object
> is already a well-understood conditional.
I've always preferred an explicit comparison to 0 or NULL rather
than if (pointer)... I can't explain why though :-) I also think
I'm not alone, do a grep "!= NULL" kernel/* :)
> > +static inline void iosync(void)
> > +{
> > + __asm__ __volatile__ ("sync" : : : "memory");
> > +}
>
> It's way more common to write 'asm volatile' instead of
> '__asm__ __volatile__' now. It's also nicer on the eye.
It is. Those are things I haven't touched though, just moved around. I
could do that additional cleanup pass I suppose.
> > + */
> > + ppc_pci_io.readb = iseries_readb;
> > + ppc_pci_io.readw = iseries_readw;
> > + ppc_pci_io.readl = iseries_readl;
> > + ppc_pci_io.readw_be = iseries_readw_be;
> > + ppc_pci_io.readl_be = iseries_readl_be;
> > + ppc_pci_io.writeb = iseries_writeb;
> > + ppc_pci_io.writew = iseries_writew;
> > + ppc_pci_io.writel = iseries_writel;
> > + ppc_pci_io.writew_be = iseries_writew_be;
> > + ppc_pci_io.writel_be = iseries_writel_be;
> > + ppc_pci_io.readsb = iseries_readsb;
> > + ppc_pci_io.readsw = iseries_readsw;
> > + ppc_pci_io.readsl = iseries_readsl;
> > + ppc_pci_io.writesb = iseries_writesb;
> > + ppc_pci_io.writesw = iseries_writesw;
> > + ppc_pci_io.writesl = iseries_writesl;
> > + ppc_pci_io.memset_io = iseries_memset_io;
> > + ppc_pci_io.memcpy_fromio = iseries_memcpy_fromio;
> > + ppc_pci_io.memcpy_toio = iseries_memcpy_toio;
>
> I guess it would be slightly more readable and more space
> efficient to write this as
>
> static struct ppc_pci_io __initdata iseries_pci_io = {
> .readb = iseries_readb;
> .readw = iseries_readw;
> .readl = iseries_readl;
> .readw_be = iseries_readw_be;
> .readl_be = iseries_readl_be;
> .writeb = iseries_writeb;
> .writew = iseries_writew;
> .writel = iseries_writel;
> .writew_be = iseries_writew_be;
> .writel_be = iseries_writel_be;
> .readsb = iseries_readsb;
> .readsw = iseries_readsw;
> .readsl = iseries_readsl;
> .writesb = iseries_writesb;
> .writesw = iseries_writesw;
> .writesl = iseries_writesl;
> .memset_io = iseries_memset_io;
> .memcpy_fromio = iseries_memcpy_fromio;
> .memcpy_toio = iseries_memcpy_toio;
> };
> ppc_pci_io = iseries_pci_io;
Indeed.
Thanks.
Ben.
^ permalink raw reply
* ppc32 PIO recovery mecanism
From: Benjamin Herrenschmidt @ 2006-11-06 0:41 UTC (permalink / raw)
To: David Woodhouse, Olaf Hering; +Cc: linuxppc-dev list
On 32 bits powerpc, we currently have a mechanism where we try to
recover from machine checks happening on PIO operations (inb/outb/....).
This mecanisms has proven of dubious reliability in the past and it's my
understanding that we've pretty fixed all relevant legacy drivers that
distro typically load so that they don't muck around when they
shouldn't.
I'm currently merging 32 and 64 bits io.h and I would really like to
just get rid of that stuff, but I'd like your distro point of view
first. Is this mechanism still useful at all or not ?
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH 2.6.19 1/4] ehca: assure 4k alignment for firmware control block in 64k page mode
From: Arnd Bergmann @ 2006-11-05 23:45 UTC (permalink / raw)
To: linuxppc-dev; +Cc: linux-kernel, raisch, openib-general
In-Reply-To: <200611052140.38445.hnguyen@de.ibm.com>
On Sunday 05 November 2006 21:40, Hoang-Nam Nguyen wrote:
> +/* constructor ctblk_cache */
> +void ehca_ctblk_ctor(void *ptr, kmem_cache_t *cache, unsigned long flags)
> +{
> + memset(ptr, 0, EHCA_PAGESIZE);
> +}
> +
> +void *ehca_alloc_fw_ctrlblock(void)
> +{
> + void *ret =3D kmem_cache_alloc(ctblk_cache, SLAB_KERNEL);
> + if (!ret)
> + =A0ehca_gen_err("Out of memory for ctblk");
> + return ret;
> +}
> +
> +void ehca_free_fw_ctrlblock(void *ptr)
> +{
> + if (ptr)
> + =A0kmem_cache_free(ctblk_cache, ptr);
> +
This seems broken. You have a constructor for newly allocated objects, but
there is no destructor and it seems that objects passed to
ehca_free_fw_ctrlblock are not guaranteed to be initialized either.
I'd simply move the memset into the alloc function and get rid of the
constructor here.
Arnd <><
^ permalink raw reply
* Re: [PATCH/RFC] Hookable IO operations #3
From: Arnd Bergmann @ 2006-11-05 23:38 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1162710572.28571.225.camel@localhost.localdomain>
On Sunday 05 November 2006 08:09, Benjamin Herrenschmidt wrote:
> [This is version 3 of the patch. It grew bigger as I added new
> base operations in order to fully support the iomap API. It works
> along with the patch from Linus:
Looks really good now, I only have a few unimportant comments about
coding style left:
> +/* The inline wrappers */
> +#define DEF_PCI_AC_RET(name, ret, at, al) \
> +static inline ret name at \
> +{ \
> + if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL) \
> + return ppc_pci_io.name al; \
> + return __do_##name al; \
> +}
Why do you write stuff like
if (pointer != NULL) ?
It looks really pointless, since the existence of the object
is already a well-understood conditional.
After all, you don't write
if ((pointer == NULL) == false)
;-)
> +static inline void iosync(void)
> +{
> + __asm__ __volatile__ ("sync" : : : "memory");
> +}
It's way more common to write 'asm volatile' instead of
'__asm__ __volatile__' now. It's also nicer on the eye.
> + */
> + ppc_pci_io.readb = iseries_readb;
> + ppc_pci_io.readw = iseries_readw;
> + ppc_pci_io.readl = iseries_readl;
> + ppc_pci_io.readw_be = iseries_readw_be;
> + ppc_pci_io.readl_be = iseries_readl_be;
> + ppc_pci_io.writeb = iseries_writeb;
> + ppc_pci_io.writew = iseries_writew;
> + ppc_pci_io.writel = iseries_writel;
> + ppc_pci_io.writew_be = iseries_writew_be;
> + ppc_pci_io.writel_be = iseries_writel_be;
> + ppc_pci_io.readsb = iseries_readsb;
> + ppc_pci_io.readsw = iseries_readsw;
> + ppc_pci_io.readsl = iseries_readsl;
> + ppc_pci_io.writesb = iseries_writesb;
> + ppc_pci_io.writesw = iseries_writesw;
> + ppc_pci_io.writesl = iseries_writesl;
> + ppc_pci_io.memset_io = iseries_memset_io;
> + ppc_pci_io.memcpy_fromio = iseries_memcpy_fromio;
> + ppc_pci_io.memcpy_toio = iseries_memcpy_toio;
I guess it would be slightly more readable and more space
efficient to write this as
static struct ppc_pci_io __initdata iseries_pci_io = {
.readb = iseries_readb;
.readw = iseries_readw;
.readl = iseries_readl;
.readw_be = iseries_readw_be;
.readl_be = iseries_readl_be;
.writeb = iseries_writeb;
.writew = iseries_writew;
.writel = iseries_writel;
.writew_be = iseries_writew_be;
.writel_be = iseries_writel_be;
.readsb = iseries_readsb;
.readsw = iseries_readsw;
.readsl = iseries_readsl;
.writesb = iseries_writesb;
.writesw = iseries_writesw;
.writesl = iseries_writesl;
.memset_io = iseries_memset_io;
.memcpy_fromio = iseries_memcpy_fromio;
.memcpy_toio = iseries_memcpy_toio;
};
ppc_pci_io = iseries_pci_io;
Arnd <><
^ permalink raw reply
* CONFIG_8260_PCI9 question
From: Benjamin Herrenschmidt @ 2006-11-05 22:56 UTC (permalink / raw)
To: linuxppc-dev list
include/asm-ppc/io.h has a special case for IO macros for when
CONFIG_8260_PCI9 is set.
However, I fail to see in what way those are different from the normal
ones. So I'm about to remove that gratuitous difference.
If I've missed something, please shout now.
Ben.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox