2005-04-16 15:20:36 -07:00
|
|
|
/*
|
|
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
|
|
* License. See the file "COPYING" in the main directory of this archive
|
|
|
|
* for more details.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved.
|
|
|
|
*/
|
|
|
|
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
/* This file contains the master driver module for use by SGI IOC4 subdrivers.
|
|
|
|
*
|
|
|
|
* It allocates any resources shared between multiple subdevices, and
|
|
|
|
* provides accessor functions (where needed) and the like for those
|
|
|
|
* resources. It also provides a mechanism for the subdevice modules
|
|
|
|
* to support loading and unloading.
|
|
|
|
*
|
|
|
|
* Non-shared resources (e.g. external interrupt A_INT_OUT register page
|
|
|
|
* alias, serial port and UART registers) are handled by the subdevice
|
|
|
|
* modules themselves.
|
|
|
|
*
|
|
|
|
* This is all necessary because IOC4 is not implemented as a multi-function
|
|
|
|
* PCI device, but an amalgamation of disparate registers for several
|
|
|
|
* types of device (ATA, serial, external interrupts). The normal
|
|
|
|
* resource management in the kernel doesn't have quite the right interfaces
|
|
|
|
* to handle this situation (e.g. multiple modules can't claim the same
|
|
|
|
* PCI ID), thus this IOC4 master module.
|
2005-04-16 15:20:36 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/errno.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/pci.h>
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
#include <linux/ioc4.h>
|
2005-06-21 17:16:01 -07:00
|
|
|
#include <linux/mmtimer.h>
|
|
|
|
#include <linux/rtc.h>
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
#include <linux/rwsem.h>
|
2005-06-21 17:16:01 -07:00
|
|
|
#include <asm/sn/addrs.h>
|
|
|
|
#include <asm/sn/clksupport.h>
|
|
|
|
#include <asm/sn/shub_mmr.h>
|
|
|
|
|
|
|
|
/***************
|
|
|
|
* Definitions *
|
|
|
|
***************/
|
|
|
|
|
|
|
|
/* Tweakable values */
|
|
|
|
|
|
|
|
/* PCI bus speed detection/calibration */
|
|
|
|
#define IOC4_CALIBRATE_COUNT 63 /* Calibration cycle period */
|
|
|
|
#define IOC4_CALIBRATE_CYCLES 256 /* Average over this many cycles */
|
|
|
|
#define IOC4_CALIBRATE_DISCARD 2 /* Discard first few cycles */
|
|
|
|
#define IOC4_CALIBRATE_LOW_MHZ 25 /* Lower bound on bus speed sanity */
|
|
|
|
#define IOC4_CALIBRATE_HIGH_MHZ 75 /* Upper bound on bus speed sanity */
|
|
|
|
#define IOC4_CALIBRATE_DEFAULT_MHZ 66 /* Assumed if sanity check fails */
|
2005-04-16 15:20:36 -07:00
|
|
|
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
/************************
|
|
|
|
* Submodule management *
|
|
|
|
************************/
|
2005-04-16 15:20:36 -07:00
|
|
|
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
static LIST_HEAD(ioc4_devices);
|
|
|
|
static DECLARE_RWSEM(ioc4_devices_rwsem);
|
|
|
|
|
|
|
|
static LIST_HEAD(ioc4_submodules);
|
|
|
|
static DECLARE_RWSEM(ioc4_submodules_rwsem);
|
|
|
|
|
|
|
|
/* Register an IOC4 submodule */
|
|
|
|
int
|
|
|
|
ioc4_register_submodule(struct ioc4_submodule *is)
|
|
|
|
{
|
|
|
|
struct ioc4_driver_data *idd;
|
|
|
|
|
|
|
|
down_write(&ioc4_submodules_rwsem);
|
|
|
|
list_add(&is->is_list, &ioc4_submodules);
|
|
|
|
up_write(&ioc4_submodules_rwsem);
|
|
|
|
|
|
|
|
/* Initialize submodule for each IOC4 */
|
|
|
|
if (!is->is_probe)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
down_read(&ioc4_devices_rwsem);
|
|
|
|
list_for_each_entry(idd, &ioc4_devices, idd_list) {
|
|
|
|
if (is->is_probe(idd)) {
|
|
|
|
printk(KERN_WARNING
|
|
|
|
"%s: IOC4 submodule %s probe failed "
|
|
|
|
"for pci_dev %s",
|
|
|
|
__FUNCTION__, module_name(is->is_owner),
|
|
|
|
pci_name(idd->idd_pdev));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
up_read(&ioc4_devices_rwsem);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unregister an IOC4 submodule */
|
|
|
|
void
|
|
|
|
ioc4_unregister_submodule(struct ioc4_submodule *is)
|
2005-04-16 15:20:36 -07:00
|
|
|
{
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
struct ioc4_driver_data *idd;
|
|
|
|
|
|
|
|
down_write(&ioc4_submodules_rwsem);
|
|
|
|
list_del(&is->is_list);
|
|
|
|
up_write(&ioc4_submodules_rwsem);
|
|
|
|
|
|
|
|
/* Remove submodule for each IOC4 */
|
|
|
|
if (!is->is_remove)
|
|
|
|
return;
|
|
|
|
|
|
|
|
down_read(&ioc4_devices_rwsem);
|
|
|
|
list_for_each_entry(idd, &ioc4_devices, idd_list) {
|
|
|
|
if (is->is_remove(idd)) {
|
|
|
|
printk(KERN_WARNING
|
|
|
|
"%s: IOC4 submodule %s remove failed "
|
|
|
|
"for pci_dev %s.\n",
|
|
|
|
__FUNCTION__, module_name(is->is_owner),
|
|
|
|
pci_name(idd->idd_pdev));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
up_read(&ioc4_devices_rwsem);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************
|
|
|
|
* Device management *
|
|
|
|
*********************/
|
|
|
|
|
2005-06-21 17:16:01 -07:00
|
|
|
#define IOC4_CALIBRATE_LOW_LIMIT \
|
|
|
|
(1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_LOW_MHZ)
|
|
|
|
#define IOC4_CALIBRATE_HIGH_LIMIT \
|
|
|
|
(1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_HIGH_MHZ)
|
|
|
|
#define IOC4_CALIBRATE_DEFAULT \
|
|
|
|
(1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_DEFAULT_MHZ)
|
|
|
|
|
|
|
|
#define IOC4_CALIBRATE_END \
|
|
|
|
(IOC4_CALIBRATE_CYCLES + IOC4_CALIBRATE_DISCARD)
|
|
|
|
|
|
|
|
#define IOC4_INT_OUT_MODE_TOGGLE 0x7 /* Toggle INT_OUT every COUNT+1 ticks */
|
|
|
|
|
|
|
|
/* Determines external interrupt output clock period of the PCI bus an
|
|
|
|
* IOC4 is attached to. This value can be used to determine the PCI
|
|
|
|
* bus speed.
|
|
|
|
*
|
|
|
|
* IOC4 has a design feature that various internal timers are derived from
|
|
|
|
* the PCI bus clock. This causes IOC4 device drivers to need to take the
|
|
|
|
* bus speed into account when setting various register values (e.g. INT_OUT
|
|
|
|
* register COUNT field, UART divisors, etc). Since this information is
|
|
|
|
* needed by several subdrivers, it is determined by the main IOC4 driver,
|
|
|
|
* even though the following code utilizes external interrupt registers
|
|
|
|
* to perform the speed calculation.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
ioc4_clock_calibrate(struct ioc4_driver_data *idd)
|
|
|
|
{
|
|
|
|
extern unsigned long sn_rtc_cycles_per_second;
|
|
|
|
union ioc4_int_out int_out;
|
|
|
|
union ioc4_gpcr gpcr;
|
|
|
|
unsigned int state, last_state = 1;
|
|
|
|
uint64_t start = 0, end, period;
|
|
|
|
unsigned int count = 0;
|
|
|
|
|
|
|
|
/* Enable output */
|
|
|
|
gpcr.raw = 0;
|
|
|
|
gpcr.fields.dir = IOC4_GPCR_DIR_0;
|
|
|
|
gpcr.fields.int_out_en = 1;
|
|
|
|
writel(gpcr.raw, &idd->idd_misc_regs->gpcr_s.raw);
|
|
|
|
|
|
|
|
/* Reset to power-on state */
|
|
|
|
writel(0, &idd->idd_misc_regs->int_out.raw);
|
|
|
|
mmiowb();
|
|
|
|
|
|
|
|
printk(KERN_INFO
|
|
|
|
"%s: Calibrating PCI bus speed "
|
|
|
|
"for pci_dev %s ... ", __FUNCTION__, pci_name(idd->idd_pdev));
|
|
|
|
/* Set up square wave */
|
|
|
|
int_out.raw = 0;
|
|
|
|
int_out.fields.count = IOC4_CALIBRATE_COUNT;
|
|
|
|
int_out.fields.mode = IOC4_INT_OUT_MODE_TOGGLE;
|
|
|
|
int_out.fields.diag = 0;
|
|
|
|
writel(int_out.raw, &idd->idd_misc_regs->int_out.raw);
|
|
|
|
mmiowb();
|
|
|
|
|
|
|
|
/* Check square wave period averaged over some number of cycles */
|
|
|
|
do {
|
|
|
|
int_out.raw = readl(&idd->idd_misc_regs->int_out.raw);
|
|
|
|
state = int_out.fields.int_out;
|
|
|
|
if (!last_state && state) {
|
|
|
|
count++;
|
|
|
|
if (count == IOC4_CALIBRATE_END) {
|
|
|
|
end = rtc_time();
|
|
|
|
break;
|
|
|
|
} else if (count == IOC4_CALIBRATE_DISCARD)
|
|
|
|
start = rtc_time();
|
|
|
|
}
|
|
|
|
last_state = state;
|
|
|
|
} while (1);
|
|
|
|
|
|
|
|
/* Calculation rearranged to preserve intermediate precision.
|
|
|
|
* Logically:
|
|
|
|
* 1. "end - start" gives us number of RTC cycles over all the
|
|
|
|
* square wave cycles measured.
|
|
|
|
* 2. Divide by number of square wave cycles to get number of
|
|
|
|
* RTC cycles per square wave cycle.
|
|
|
|
* 3. Divide by 2*(int_out.fields.count+1), which is the formula
|
|
|
|
* by which the IOC4 generates the square wave, to get the
|
|
|
|
* number of RTC cycles per IOC4 INT_OUT count.
|
|
|
|
* 4. Divide by sn_rtc_cycles_per_second to get seconds per
|
|
|
|
* count.
|
|
|
|
* 5. Multiply by 1E9 to get nanoseconds per count.
|
|
|
|
*/
|
|
|
|
period = ((end - start) * 1000000000) /
|
|
|
|
(IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1)
|
|
|
|
* sn_rtc_cycles_per_second);
|
|
|
|
|
|
|
|
/* Bounds check the result. */
|
|
|
|
if (period > IOC4_CALIBRATE_LOW_LIMIT ||
|
|
|
|
period < IOC4_CALIBRATE_HIGH_LIMIT) {
|
|
|
|
printk("failed. Assuming PCI clock ticks are %d ns.\n",
|
|
|
|
IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR);
|
|
|
|
period = IOC4_CALIBRATE_DEFAULT;
|
|
|
|
} else {
|
|
|
|
printk("succeeded. PCI clock ticks are %ld ns.\n",
|
|
|
|
period / IOC4_EXTINT_COUNT_DIVISOR);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remember results. We store the extint clock period rather
|
|
|
|
* than the PCI clock period so that greater precision is
|
|
|
|
* retained. Divide by IOC4_EXTINT_COUNT_DIVISOR to get
|
|
|
|
* PCI clock period.
|
|
|
|
*/
|
|
|
|
idd->count_period = period;
|
|
|
|
}
|
|
|
|
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
/* Adds a new instance of an IOC4 card */
|
|
|
|
static int
|
|
|
|
ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
|
|
|
|
{
|
|
|
|
struct ioc4_driver_data *idd;
|
|
|
|
struct ioc4_submodule *is;
|
|
|
|
uint32_t pcmd;
|
2005-04-16 15:20:36 -07:00
|
|
|
int ret;
|
|
|
|
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
/* Enable IOC4 and take ownership of it */
|
2005-04-16 15:20:36 -07:00
|
|
|
if ((ret = pci_enable_device(pdev))) {
|
|
|
|
printk(KERN_WARNING
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
"%s: Failed to enable IOC4 device for pci_dev %s.\n",
|
|
|
|
__FUNCTION__, pci_name(pdev));
|
|
|
|
goto out;
|
2005-04-16 15:20:36 -07:00
|
|
|
}
|
|
|
|
pci_set_master(pdev);
|
|
|
|
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
/* Set up per-IOC4 data */
|
|
|
|
idd = kmalloc(sizeof(struct ioc4_driver_data), GFP_KERNEL);
|
|
|
|
if (!idd) {
|
|
|
|
printk(KERN_WARNING
|
|
|
|
"%s: Failed to allocate IOC4 data for pci_dev %s.\n",
|
|
|
|
__FUNCTION__, pci_name(pdev));
|
|
|
|
ret = -ENODEV;
|
|
|
|
goto out_idd;
|
|
|
|
}
|
|
|
|
idd->idd_pdev = pdev;
|
|
|
|
idd->idd_pci_id = pci_id;
|
|
|
|
|
|
|
|
/* Map IOC4 misc registers. These are shared between subdevices
|
|
|
|
* so the main IOC4 module manages them.
|
|
|
|
*/
|
|
|
|
idd->idd_bar0 = pci_resource_start(idd->idd_pdev, 0);
|
|
|
|
if (!idd->idd_bar0) {
|
|
|
|
printk(KERN_WARNING
|
|
|
|
"%s: Unable to find IOC4 misc resource "
|
|
|
|
"for pci_dev %s.\n",
|
|
|
|
__FUNCTION__, pci_name(idd->idd_pdev));
|
|
|
|
ret = -ENODEV;
|
|
|
|
goto out_pci;
|
|
|
|
}
|
|
|
|
if (!request_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs),
|
|
|
|
"ioc4_misc")) {
|
|
|
|
printk(KERN_WARNING
|
|
|
|
"%s: Unable to request IOC4 misc region "
|
|
|
|
"for pci_dev %s.\n",
|
|
|
|
__FUNCTION__, pci_name(idd->idd_pdev));
|
|
|
|
ret = -ENODEV;
|
|
|
|
goto out_pci;
|
|
|
|
}
|
|
|
|
idd->idd_misc_regs = ioremap(idd->idd_bar0,
|
|
|
|
sizeof(struct ioc4_misc_regs));
|
|
|
|
if (!idd->idd_misc_regs) {
|
|
|
|
printk(KERN_WARNING
|
|
|
|
"%s: Unable to remap IOC4 misc region "
|
|
|
|
"for pci_dev %s.\n",
|
|
|
|
__FUNCTION__, pci_name(idd->idd_pdev));
|
|
|
|
ret = -ENODEV;
|
|
|
|
goto out_misc_region;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Failsafe portion of per-IOC4 initialization */
|
|
|
|
|
|
|
|
/* Initialize IOC4 */
|
|
|
|
pci_read_config_dword(idd->idd_pdev, PCI_COMMAND, &pcmd);
|
|
|
|
pci_write_config_dword(idd->idd_pdev, PCI_COMMAND,
|
|
|
|
pcmd | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
|
|
|
|
|
2005-06-21 17:16:01 -07:00
|
|
|
/* Determine PCI clock */
|
|
|
|
ioc4_clock_calibrate(idd);
|
|
|
|
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
/* Disable/clear all interrupts. Need to do this here lest
|
|
|
|
* one submodule request the shared IOC4 IRQ, but interrupt
|
|
|
|
* is generated by a different subdevice.
|
|
|
|
*/
|
|
|
|
/* Disable */
|
|
|
|
writel(~0, &idd->idd_misc_regs->other_iec.raw);
|
|
|
|
writel(~0, &idd->idd_misc_regs->sio_iec);
|
|
|
|
/* Clear (i.e. acknowledge) */
|
|
|
|
writel(~0, &idd->idd_misc_regs->other_ir.raw);
|
|
|
|
writel(~0, &idd->idd_misc_regs->sio_ir);
|
|
|
|
|
|
|
|
/* Track PCI-device specific data */
|
|
|
|
idd->idd_serial_data = NULL;
|
|
|
|
pci_set_drvdata(idd->idd_pdev, idd);
|
|
|
|
down_write(&ioc4_devices_rwsem);
|
|
|
|
list_add(&idd->idd_list, &ioc4_devices);
|
|
|
|
up_write(&ioc4_devices_rwsem);
|
|
|
|
|
|
|
|
/* Add this IOC4 to all submodules */
|
|
|
|
down_read(&ioc4_submodules_rwsem);
|
|
|
|
list_for_each_entry(is, &ioc4_submodules, is_list) {
|
|
|
|
if (is->is_probe && is->is_probe(idd)) {
|
|
|
|
printk(KERN_WARNING
|
|
|
|
"%s: IOC4 submodule 0x%s probe failed "
|
|
|
|
"for pci_dev %s.\n",
|
|
|
|
__FUNCTION__, module_name(is->is_owner),
|
|
|
|
pci_name(idd->idd_pdev));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
up_read(&ioc4_submodules_rwsem);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
out_misc_region:
|
|
|
|
release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
|
|
|
|
out_pci:
|
|
|
|
kfree(idd);
|
|
|
|
out_idd:
|
|
|
|
pci_disable_device(pdev);
|
|
|
|
out:
|
|
|
|
return ret;
|
2005-04-16 15:20:36 -07:00
|
|
|
}
|
|
|
|
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
/* Removes a particular instance of an IOC4 card. */
|
|
|
|
static void
|
|
|
|
ioc4_remove(struct pci_dev *pdev)
|
|
|
|
{
|
|
|
|
struct ioc4_submodule *is;
|
|
|
|
struct ioc4_driver_data *idd;
|
|
|
|
|
|
|
|
idd = pci_get_drvdata(pdev);
|
|
|
|
|
|
|
|
/* Remove this IOC4 from all submodules */
|
|
|
|
down_read(&ioc4_submodules_rwsem);
|
|
|
|
list_for_each_entry(is, &ioc4_submodules, is_list) {
|
|
|
|
if (is->is_remove && is->is_remove(idd)) {
|
|
|
|
printk(KERN_WARNING
|
|
|
|
"%s: IOC4 submodule 0x%s remove failed "
|
|
|
|
"for pci_dev %s.\n",
|
|
|
|
__FUNCTION__, module_name(is->is_owner),
|
|
|
|
pci_name(idd->idd_pdev));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
up_read(&ioc4_submodules_rwsem);
|
|
|
|
|
|
|
|
/* Release resources */
|
|
|
|
iounmap(idd->idd_misc_regs);
|
|
|
|
if (!idd->idd_bar0) {
|
|
|
|
printk(KERN_WARNING
|
|
|
|
"%s: Unable to get IOC4 misc mapping for pci_dev %s. "
|
|
|
|
"Device removal may be incomplete.\n",
|
|
|
|
__FUNCTION__, pci_name(idd->idd_pdev));
|
|
|
|
}
|
|
|
|
release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
|
|
|
|
|
|
|
|
/* Disable IOC4 and relinquish */
|
|
|
|
pci_disable_device(pdev);
|
|
|
|
|
|
|
|
/* Remove and free driver data */
|
|
|
|
down_write(&ioc4_devices_rwsem);
|
|
|
|
list_del(&idd->idd_list);
|
|
|
|
up_write(&ioc4_devices_rwsem);
|
|
|
|
kfree(idd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct pci_device_id ioc4_id_table[] = {
|
2005-04-16 15:20:36 -07:00
|
|
|
{PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC4, PCI_ANY_ID,
|
|
|
|
PCI_ANY_ID, 0x0b4000, 0xFFFFFF},
|
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
static struct pci_driver __devinitdata ioc4_driver = {
|
|
|
|
.name = "IOC4",
|
|
|
|
.id_table = ioc4_id_table,
|
|
|
|
.probe = ioc4_probe,
|
|
|
|
.remove = ioc4_remove,
|
2005-04-16 15:20:36 -07:00
|
|
|
};
|
|
|
|
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
MODULE_DEVICE_TABLE(pci, ioc4_id_table);
|
|
|
|
|
|
|
|
/*********************
|
|
|
|
* Module management *
|
|
|
|
*********************/
|
|
|
|
|
|
|
|
/* Module load */
|
|
|
|
static int __devinit
|
|
|
|
ioc4_init(void)
|
2005-04-16 15:20:36 -07:00
|
|
|
{
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
return pci_register_driver(&ioc4_driver);
|
|
|
|
}
|
2005-04-16 15:20:36 -07:00
|
|
|
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
/* Module unload */
|
|
|
|
static void __devexit
|
|
|
|
ioc4_exit(void)
|
|
|
|
{
|
|
|
|
pci_unregister_driver(&ioc4_driver);
|
2005-04-16 15:20:36 -07:00
|
|
|
}
|
|
|
|
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
module_init(ioc4_init);
|
|
|
|
module_exit(ioc4_exit);
|
|
|
|
|
|
|
|
MODULE_AUTHOR("Brent Casavant - Silicon Graphics, Inc. <bcasavan@sgi.com>");
|
|
|
|
MODULE_DESCRIPTION("PCI driver master module for SGI IOC4 Base-IO Card");
|
2005-04-16 15:20:36 -07:00
|
|
|
MODULE_LICENSE("GPL");
|
[PATCH] ioc4: Core driver rewrite
This series of patches reworks the configuration and internal structure
of the SGI IOC4 I/O controller device drivers.
These changes are motivated by several factors:
- The IOC4 chip PCI resources are of mixed use between functions (i.e.
multiple functions are handled in the same address range, sometimes
within the same register), muddling resource ownership and initialization
issues. Centralizing this ownership in a core driver is desirable.
- The IOC4 chip implements multiple functions (serial, IDE, others not
yet implemented in the mainline kernel) but is not a multifunction
PCI device. In order to properly handle device addition and removal
as well as module insertion and deletion, an intermediary IOC4-specific
driver layer is needed to handle these operations cleanly.
- All IOC4 drivers are currently enabled by a single CONFIG value. As
not all systems need all IOC4 functions, it is desireable to enable
these drivers independently.
- The current IOC4 core driver will trigger loading of all function-level
drivers, as it makes direct calls to them. This situation should be
reversed (i.e. function-level drivers cause loading of core driver)
in order to maintain a clear and least-surprise driver loading model.
- IOC4 hardware design necessitates some driver-level dependency on
the PCI bus clock speed. Current code assumes a 66MHz bus, but the
speed should be autodetected and appropriate compensation taken.
This patch series effects the above changes by a newly and better designed
IOC4 core driver with which the function-level drivers can register and
deregister themselves upon module insertion/removal. By tracking these
modules, device addition/removal is also handled properly. PCI resource
management and ownership issues are centralized in this core driver, and
IOC4-wide configuration actions such as bus speed detection are also
handled in this core driver.
This patch:
The SGI IOC4 I/O controller chip implements multiple functions, though it is
not a multi-function PCI device. Additionally, various PCI resources of the
IOC4 are shared by multiple hardware functions, and thus resource ownership by
driver is not clearly delineated. Due to the current driver design, all core
and subordinate drivers must be loaded, or none, which is undesirable if not
all IOC4 hardware features are being used.
This patch reorganizes the IOC4 drivers so that the core driver provides a
subdriver registration service. Through appropriate callbacks the subdrivers
can now handle device addition and removal, as well as module insertion and
deletion (though the IOC4 IDE driver requires further work before module
deletion will work). The core driver now takes care of allocating PCI
resources and data which must be shared between subdrivers, to clearly
delineate module ownership of these items.
Signed-off-by: Brent Casavant <bcasavan@sgi.com>
Acked-by: Pat Gefre <pfg@sgi.com
Acked-by: Jeremy Higdon <jeremy@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-21 17:15:59 -07:00
|
|
|
|
|
|
|
EXPORT_SYMBOL(ioc4_register_submodule);
|
|
|
|
EXPORT_SYMBOL(ioc4_unregister_submodule);
|