Commit 86349f7c authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/home/davem/src/BK/network-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents a119e8a4 c2769b50
...@@ -801,20 +801,13 @@ P: Oliver Neukum ...@@ -801,20 +801,13 @@ P: Oliver Neukum
M: drivers@neukum.org M: drivers@neukum.org
S: Maintained S: Maintained
I2C DRIVERS I2C AND SENSORS DRIVERS
P: Simon Vogl
M: simon@tk.uni-linz.ac.at
P: Frodo Looijaard
M: frodol@dds.nl
L: linux-i2c@pelican.tk.uni-linz.ac.at
W: http://www.tk.uni-linz.ac.at/~simon/private/i2c
S: Maintained
SENSORS DRIVERS
P: Frodo Looijaard P: Frodo Looijaard
M: frodol@dds.nl M: frodol@dds.nl
P: Philip Edelbrock P: Philip Edelbrock
M: phil@netroedge.com M: phil@netroedge.com
P: Greg Kroah-Hartman
M: greg@kroah.com
L: sensors@stimpy.netroedge.com L: sensors@stimpy.netroedge.com
W: http://www.lm-sensors.nu/ W: http://www.lm-sensors.nu/
S: Maintained S: Maintained
......
...@@ -80,6 +80,7 @@ EXPORT_SYMBOL(acpi_get_current_resources); ...@@ -80,6 +80,7 @@ EXPORT_SYMBOL(acpi_get_current_resources);
EXPORT_SYMBOL(acpi_get_possible_resources); EXPORT_SYMBOL(acpi_get_possible_resources);
EXPORT_SYMBOL(acpi_walk_resources); EXPORT_SYMBOL(acpi_walk_resources);
EXPORT_SYMBOL(acpi_set_current_resources); EXPORT_SYMBOL(acpi_set_current_resources);
EXPORT_SYMBOL(acpi_resource_to_address64);
EXPORT_SYMBOL(acpi_enable_event); EXPORT_SYMBOL(acpi_enable_event);
EXPORT_SYMBOL(acpi_disable_event); EXPORT_SYMBOL(acpi_disable_event);
EXPORT_SYMBOL(acpi_clear_event); EXPORT_SYMBOL(acpi_clear_event);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Al Longyear <longyear@netcom.com>, Paul Mackerras <Paul.Mackerras@cs.anu.edu.au> * Al Longyear <longyear@netcom.com>, Paul Mackerras <Paul.Mackerras@cs.anu.edu.au>
* *
* Original release 01/11/99 * Original release 01/11/99
* $Id: n_hdlc.c,v 4.6 2003/04/21 19:14:07 paulkf Exp $ * $Id: n_hdlc.c,v 4.8 2003/05/06 21:18:51 paulkf Exp $
* *
* This code is released under the GNU General Public License (GPL) * This code is released under the GNU General Public License (GPL)
* *
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
*/ */
#define HDLC_MAGIC 0x239e #define HDLC_MAGIC 0x239e
#define HDLC_VERSION "$Revision: 4.6 $" #define HDLC_VERSION "$Revision: 4.8 $"
#include <linux/version.h> #include <linux/version.h>
#include <linux/config.h> #include <linux/config.h>
...@@ -215,6 +215,21 @@ static void n_hdlc_tty_wakeup (struct tty_struct *tty); ...@@ -215,6 +215,21 @@ static void n_hdlc_tty_wakeup (struct tty_struct *tty);
/* Define this string only once for all macro invocations */ /* Define this string only once for all macro invocations */
static char szVersion[] = HDLC_VERSION; static char szVersion[] = HDLC_VERSION;
static struct tty_ldisc n_hdlc_ldisc = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC,
.name = "hdlc",
.open = n_hdlc_tty_open,
.close = n_hdlc_tty_close,
.read = n_hdlc_tty_read,
.write = n_hdlc_tty_write,
.ioctl = n_hdlc_tty_ioctl,
.poll = n_hdlc_tty_poll,
.receive_buf = n_hdlc_tty_receive,
.receive_room = n_hdlc_tty_room,
.write_wakeup = n_hdlc_tty_wakeup,
};
/* n_hdlc_release() /* n_hdlc_release()
* *
* release an n_hdlc per device line discipline info structure * release an n_hdlc per device line discipline info structure
...@@ -968,25 +983,6 @@ static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list) ...@@ -968,25 +983,6 @@ static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list)
static int __init n_hdlc_init(void) static int __init n_hdlc_init(void)
{ {
static struct tty_ldisc n_hdlc_ldisc = {
TTY_LDISC_MAGIC, /* magic */
"hdlc", /* name */
0, /* num */
0, /* flags */
n_hdlc_tty_open, /* open */
n_hdlc_tty_close, /* close */
0, /* flush_buffer */
0, /* chars_in_buffer */
n_hdlc_tty_read, /* read */
n_hdlc_tty_write, /* write */
n_hdlc_tty_ioctl, /* ioctl */
0, /* set_termios */
n_hdlc_tty_poll, /* poll */
n_hdlc_tty_receive, /* receive_buf */
n_hdlc_tty_room, /* receive_room */
n_hdlc_tty_wakeup, /* write_wakeup */
THIS_MODULE /* owner */
};
int status; int status;
/* range check maxframe arg */ /* range check maxframe arg */
......
/* /*
* linux/drivers/char/synclink.c * linux/drivers/char/synclink.c
* *
* $Id: synclink.c,v 4.6 2003/04/21 17:46:54 paulkf Exp $ * $Id: synclink.c,v 4.9 2003/05/06 21:18:51 paulkf Exp $
* *
* Device driver for Microgate SyncLink ISA and PCI * Device driver for Microgate SyncLink ISA and PCI
* high speed multiprotocol serial adapters. * high speed multiprotocol serial adapters.
...@@ -193,6 +193,7 @@ struct mgsl_struct { ...@@ -193,6 +193,7 @@ struct mgsl_struct {
int flags; int flags;
int count; /* count of opens */ int count; /* count of opens */
int line; int line;
int hw_version;
unsigned short close_delay; unsigned short close_delay;
unsigned short closing_wait; /* time to wait before closing */ unsigned short closing_wait; /* time to wait before closing */
...@@ -917,7 +918,7 @@ MODULE_PARM(txdmabufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i"); ...@@ -917,7 +918,7 @@ MODULE_PARM(txdmabufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
MODULE_PARM(txholdbufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i"); MODULE_PARM(txholdbufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
static char *driver_name = "SyncLink serial driver"; static char *driver_name = "SyncLink serial driver";
static char *driver_version = "$Revision: 4.6 $"; static char *driver_version = "$Revision: 4.9 $";
static int synclink_init_one (struct pci_dev *dev, static int synclink_init_one (struct pci_dev *dev,
const struct pci_device_id *ent); const struct pci_device_id *ent);
...@@ -925,6 +926,7 @@ static void synclink_remove_one (struct pci_dev *dev); ...@@ -925,6 +926,7 @@ static void synclink_remove_one (struct pci_dev *dev);
static struct pci_device_id synclink_pci_tbl[] __devinitdata = { static struct pci_device_id synclink_pci_tbl[] __devinitdata = {
{ PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_USC, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_USC, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_MICROGATE, 0x0210, PCI_ANY_ID, PCI_ANY_ID, },
{ 0, }, /* terminate list */ { 0, }, /* terminate list */
}; };
MODULE_DEVICE_TABLE(pci, synclink_pci_tbl); MODULE_DEVICE_TABLE(pci, synclink_pci_tbl);
...@@ -4216,9 +4218,7 @@ int load_next_tx_holding_buffer(struct mgsl_struct *info) ...@@ -4216,9 +4218,7 @@ int load_next_tx_holding_buffer(struct mgsl_struct *info)
info->get_tx_holding_index=0; info->get_tx_holding_index=0;
/* restart transmit timer */ /* restart transmit timer */
del_timer(&info->tx_timer); mod_timer(&info->tx_timer, jiffies + jiffies_from_ms(5000));
info->tx_timer.expires = jiffies + jiffies_from_ms(5000);
add_timer(&info->tx_timer);
ret = 1; ret = 1;
} }
...@@ -4436,12 +4436,12 @@ void mgsl_add_device( struct mgsl_struct *info ) ...@@ -4436,12 +4436,12 @@ void mgsl_add_device( struct mgsl_struct *info )
info->max_frame_size = 65535; info->max_frame_size = 65535;
if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
printk( "SyncLink device %s added:PCI bus IO=%04X IRQ=%d Mem=%08X LCR=%08X MaxFrameSize=%u\n", printk( "SyncLink PCI v%d %s: IO=%04X IRQ=%d Mem=%08X,%08X MaxFrameSize=%u\n",
info->device_name, info->io_base, info->irq_level, info->hw_version + 1, info->device_name, info->io_base, info->irq_level,
info->phys_memory_base, info->phys_lcr_base, info->phys_memory_base, info->phys_lcr_base,
info->max_frame_size ); info->max_frame_size );
} else { } else {
printk( "SyncLink device %s added:ISA bus IO=%04X IRQ=%d DMA=%d MaxFrameSize=%u\n", printk( "SyncLink ISA %s: IO=%04X IRQ=%d DMA=%d MaxFrameSize=%u\n",
info->device_name, info->io_base, info->irq_level, info->dma_level, info->device_name, info->io_base, info->irq_level, info->dma_level,
info->max_frame_size ); info->max_frame_size );
} }
...@@ -5296,10 +5296,11 @@ void usc_set_sdlc_mode( struct mgsl_struct *info ) ...@@ -5296,10 +5296,11 @@ void usc_set_sdlc_mode( struct mgsl_struct *info )
info->mbre_bit = BIT8; info->mbre_bit = BIT8;
outw( BIT8, info->io_base ); /* set Master Bus Enable (DCAR) */ outw( BIT8, info->io_base ); /* set Master Bus Enable (DCAR) */
if (info->bus_type == MGSL_BUS_TYPE_ISA) {
/* Enable DMAEN (Port 7, Bit 14) */ /* Enable DMAEN (Port 7, Bit 14) */
/* This connects the DMA request signal to the ISA bus */ /* This connects the DMA request signal to the ISA bus */
/* on the ISA adapter. This has no effect for the PCI adapter */ usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT15) & ~BIT14));
usc_OutReg( info, PCR, (u16)((usc_InReg(info, PCR) | BIT15) & ~BIT14) ); }
/* DMA Control Register (DCR) /* DMA Control Register (DCR)
* *
...@@ -6276,10 +6277,11 @@ void usc_set_async_mode( struct mgsl_struct *info ) ...@@ -6276,10 +6277,11 @@ void usc_set_async_mode( struct mgsl_struct *info )
usc_EnableMasterIrqBit( info ); usc_EnableMasterIrqBit( info );
if (info->bus_type == MGSL_BUS_TYPE_ISA) {
/* Enable INTEN (Port 6, Bit12) */ /* Enable INTEN (Port 6, Bit12) */
/* This connects the IRQ request signal to the ISA bus */ /* This connects the IRQ request signal to the ISA bus */
/* on the ISA adapter. This has no effect for the PCI adapter */ usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12));
usc_OutReg( info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12) ); }
} /* end of usc_set_async_mode() */ } /* end of usc_set_async_mode() */
...@@ -6370,10 +6372,11 @@ void usc_set_sync_mode( struct mgsl_struct *info ) ...@@ -6370,10 +6372,11 @@ void usc_set_sync_mode( struct mgsl_struct *info )
usc_loopback_frame( info ); usc_loopback_frame( info );
usc_set_sdlc_mode( info ); usc_set_sdlc_mode( info );
if (info->bus_type == MGSL_BUS_TYPE_ISA) {
/* Enable INTEN (Port 6, Bit12) */ /* Enable INTEN (Port 6, Bit12) */
/* This connects the IRQ request signal to the ISA bus */ /* This connects the IRQ request signal to the ISA bus */
/* on the ISA adapter. This has no effect for the PCI adapter */
usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12)); usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) & ~BIT12));
}
usc_enable_aux_clock(info, info->params.clock_speed); usc_enable_aux_clock(info, info->params.clock_speed);
...@@ -8116,16 +8119,19 @@ static int __init synclink_init_one (struct pci_dev *dev, ...@@ -8116,16 +8119,19 @@ static int __init synclink_init_one (struct pci_dev *dev,
info->io_addr_size = 8; info->io_addr_size = 8;
info->irq_flags = SA_SHIRQ; info->irq_flags = SA_SHIRQ;
/* Store the PCI9050 misc control register value because a flaw if (dev->device == 0x0210) {
* in the PCI9050 prevents LCR registers from being read if /* Version 1 PCI9030 based universal PCI adapter */
* BIOS assigns an LCR base address with bit 7 set. info->misc_ctrl_value = 0x007c4080;
* info->hw_version = 1;
* Only the misc control register is accessed for which only } else {
* write access is needed, so set an initial value and change /* Version 0 PCI9050 based 5V PCI adapter
* bits to the device instance data as we write the value * A PCI9050 bug prevents reading LCR registers if
* to the actual misc control register. * LCR base address bit 7 is set. Maintain shadow
* value so we can write to LCR misc control reg.
*/ */
info->misc_ctrl_value = 0x087e4546; info->misc_ctrl_value = 0x087e4546;
info->hw_version = 0;
}
mgsl_add_device(info); mgsl_add_device(info);
......
...@@ -61,7 +61,7 @@ config HOTPLUG_PCI_IBM ...@@ -61,7 +61,7 @@ config HOTPLUG_PCI_IBM
config HOTPLUG_PCI_ACPI config HOTPLUG_PCI_ACPI
tristate "ACPI PCI Hotplug driver" tristate "ACPI PCI Hotplug driver"
depends on ACPI && HOTPLUG_PCI depends on ACPI_BUS && HOTPLUG_PCI
help help
Say Y here if you have a system that supports PCI Hotplug using Say Y here if you have a system that supports PCI Hotplug using
ACPI. ACPI.
......
...@@ -806,6 +806,7 @@ static int enable_device (struct acpiphp_slot *slot) ...@@ -806,6 +806,7 @@ static int enable_device (struct acpiphp_slot *slot)
struct list_head *l; struct list_head *l;
struct acpiphp_func *func; struct acpiphp_func *func;
int retval = 0; int retval = 0;
int num;
if (slot->flags & SLOT_ENABLED) if (slot->flags & SLOT_ENABLED)
goto err_exit; goto err_exit;
...@@ -825,7 +826,10 @@ static int enable_device (struct acpiphp_slot *slot) ...@@ -825,7 +826,10 @@ static int enable_device (struct acpiphp_slot *slot)
goto err_exit; goto err_exit;
/* returned `dev' is the *first function* only! */ /* returned `dev' is the *first function* only! */
dev = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0)); num = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0));
if (num)
pci_bus_add_devices(slot->bridge->pci_bus);
dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
if (!dev) { if (!dev) {
err("No new device found\n"); err("No new device found\n");
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include "pci_hotplug.h" #include "pci_hotplug.h"
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <asm/io.h> /* for read? and write? functions */ #include <asm/io.h> /* for read? and write? functions */
#include <linux/delay.h> /* for delays */
#if !defined(CONFIG_HOTPLUG_PCI_COMPAQ_MODULE) #if !defined(CONFIG_HOTPLUG_PCI_COMPAQ_MODULE)
#define MY_NAME "cpqphp.o" #define MY_NAME "cpqphp.o"
...@@ -146,6 +146,10 @@ struct ctrl_reg { /* offset */ ...@@ -146,6 +146,10 @@ struct ctrl_reg { /* offset */
u8 reserved11; /* 0x2b */ u8 reserved11; /* 0x2b */
u8 slot_SERR; /* 0x2c */ u8 slot_SERR; /* 0x2c */
u8 slot_power; /* 0x2d */ u8 slot_power; /* 0x2d */
u8 reserved12; /* 0x2e */
u8 reserved13; /* 0x2f */
u8 next_curr_freq; /* 0x30 */
u8 reset_freq_mode; /* 0x31 */
} __attribute__ ((packed)); } __attribute__ ((packed));
/* offsets to the controller registers based on the above structure layout */ /* offsets to the controller registers based on the above structure layout */
...@@ -173,6 +177,8 @@ enum ctrl_offsets { ...@@ -173,6 +177,8 @@ enum ctrl_offsets {
CTRL_RESERVED11 = offsetof(struct ctrl_reg, reserved11), CTRL_RESERVED11 = offsetof(struct ctrl_reg, reserved11),
SLOT_SERR = offsetof(struct ctrl_reg, slot_SERR), SLOT_SERR = offsetof(struct ctrl_reg, slot_SERR),
SLOT_POWER = offsetof(struct ctrl_reg, slot_power), SLOT_POWER = offsetof(struct ctrl_reg, slot_power),
NEXT_CURR_FREQ = offsetof(struct ctrl_reg, next_curr_freq),
RESET_FREQ_MODE = offsetof(struct ctrl_reg, reset_freq_mode),
}; };
struct hrt { struct hrt {
...@@ -294,12 +300,11 @@ struct controller { ...@@ -294,12 +300,11 @@ struct controller {
struct pci_resource *bus_head; struct pci_resource *bus_head;
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
struct pci_bus *pci_bus; struct pci_bus *pci_bus;
struct proc_dir_entry* proc_entry;
struct proc_dir_entry* proc_entry2;
struct event_info event_queue[10]; struct event_info event_queue[10];
struct slot *slot; struct slot *slot;
u8 next_event; u8 next_event;
u8 interrupt; u8 interrupt;
u8 cfgspc_irq;
u8 bus; /* bus number for the pci hotplug controller */ u8 bus; /* bus number for the pci hotplug controller */
u8 rev; u8 rev;
u8 slot_device_offset; u8 slot_device_offset;
...@@ -316,8 +321,6 @@ struct controller { ...@@ -316,8 +321,6 @@ struct controller {
u8 pcix_speed_capability; /* PCI-X */ u8 pcix_speed_capability; /* PCI-X */
u8 pcix_support; /* PCI-X */ u8 pcix_support; /* PCI-X */
u16 vendor_id; u16 vendor_id;
char proc_name[20];
char proc_name2[20];
struct work_struct int_task_event; struct work_struct int_task_event;
wait_queue_head_t queue; /* sleep & wake process */ wait_queue_head_t queue; /* sleep & wake process */
}; };
...@@ -344,6 +347,7 @@ struct resource_lists { ...@@ -344,6 +347,7 @@ struct resource_lists {
#define PCI_SUB_HPC_ID2 0xA2F8 #define PCI_SUB_HPC_ID2 0xA2F8
#define PCI_SUB_HPC_ID3 0xA2F9 #define PCI_SUB_HPC_ID3 0xA2F9
#define PCI_SUB_HPC_ID_INTC 0xA2FA #define PCI_SUB_HPC_ID_INTC 0xA2FA
#define PCI_SUB_HPC_ID4 0xA2FD
#define INT_BUTTON_IGNORE 0 #define INT_BUTTON_IGNORE 0
#define INT_PRESENCE_ON 1 #define INT_PRESENCE_ON 1
...@@ -436,7 +440,7 @@ extern int cpqhp_return_board_resources (struct pci_func * func, struct resource ...@@ -436,7 +440,7 @@ extern int cpqhp_return_board_resources (struct pci_func * func, struct resource
extern void cpqhp_destroy_resource_list (struct resource_lists * resources); extern void cpqhp_destroy_resource_list (struct resource_lists * resources);
extern int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func); extern int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func);
extern int cpqhp_unconfigure_device (struct pci_func* func); extern int cpqhp_unconfigure_device (struct pci_func* func);
extern struct slot *cpqhp_find_slot (struct controller *ctrl, u8 device);
/* Global variables */ /* Global variables */
extern int cpqhp_debug; extern int cpqhp_debug;
...@@ -564,6 +568,7 @@ static inline void green_LED_blink (struct controller *ctrl, u8 slot) ...@@ -564,6 +568,7 @@ static inline void green_LED_blink (struct controller *ctrl, u8 slot)
u32 led_control; u32 led_control;
led_control = readl(ctrl->hpc_reg + LED_CONTROL); led_control = readl(ctrl->hpc_reg + LED_CONTROL);
led_control &= ~(0x0101L << slot);
led_control |= (0x0001L << slot); led_control |= (0x0001L << slot);
writel(led_control, ctrl->hpc_reg + LED_CONTROL); writel(led_control, ctrl->hpc_reg + LED_CONTROL);
} }
...@@ -605,15 +610,64 @@ static inline u8 read_slot_enable (struct controller *ctrl) ...@@ -605,15 +610,64 @@ static inline u8 read_slot_enable (struct controller *ctrl)
} }
/*
* get_controller_speed - find the current frequency/mode of controller.
*
* @ctrl: controller to get frequency/mode for.
*
* Returns controller speed.
*
*/
static inline u8 get_controller_speed (struct controller *ctrl) static inline u8 get_controller_speed (struct controller *ctrl)
{ {
u8 curr_freq;
u16 misc; u16 misc;
if (ctrl->pcix_support) {
curr_freq = readb(ctrl->hpc_reg + NEXT_CURR_FREQ);
if ((curr_freq & 0xB0) == 0xB0)
return PCI_SPEED_133MHz_PCIX;
if ((curr_freq & 0xA0) == 0xA0)
return PCI_SPEED_100MHz_PCIX;
if ((curr_freq & 0x90) == 0x90)
return PCI_SPEED_66MHz_PCIX;
if (curr_freq & 0x10)
return PCI_SPEED_66MHz;
return PCI_SPEED_33MHz;
}
misc = readw(ctrl->hpc_reg + MISC); misc = readw(ctrl->hpc_reg + MISC);
return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
} }
/*
* get_adapter_speed - find the max supported frequency/mode of adapter.
*
* @ctrl: hotplug controller.
* @hp_slot: hotplug slot where adapter is installed.
*
* Returns adapter speed.
*
*/
static inline u8 get_adapter_speed (struct controller *ctrl, u8 hp_slot)
{
u32 temp_dword = readl(ctrl->hpc_reg + NON_INT_INPUT);
dbg("slot: %d, PCIXCAP: %8x\n", hp_slot, temp_dword);
if (ctrl->pcix_support) {
if (temp_dword & (0x10000 << hp_slot))
return PCI_SPEED_133MHz_PCIX;
if (temp_dword & (0x100 << hp_slot))
return PCI_SPEED_66MHz_PCIX;
}
if (temp_dword & (0x01 << hp_slot))
return PCI_SPEED_66MHz;
return PCI_SPEED_33MHz;
}
static inline void enable_slot_power (struct controller *ctrl, u8 slot) static inline void enable_slot_power (struct controller *ctrl, u8 slot)
{ {
u8 slot_power; u8 slot_power;
...@@ -721,5 +775,138 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl) ...@@ -721,5 +775,138 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl)
return retval; return retval;
} }
/**
* set_controller_speed - set the frequency and/or mode of a specific
* controller segment.
*
* @ctrl: controller to change frequency/mode for.
* @adapter_speed: the speed of the adapter we want to match.
* @hp_slot: the slot number where the adapter is installed.
*
* Returns 0 if we successfully change frequency and/or mode to match the
* adapter speed.
*
*/
static inline u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_slot)
{
struct slot *slot;
u8 reg;
u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
u16 reg16;
u32 leds = readl(ctrl->hpc_reg + LED_CONTROL);
if (ctrl->speed == adapter_speed)
return 0;
/* We don't allow freq/mode changes if we find another adapter running
* in another slot on this controller */
for(slot = ctrl->slot; slot; slot = slot->next) {
if (slot->device == (hp_slot + ctrl->slot_device_offset))
continue;
if (!slot->hotplug_slot && !slot->hotplug_slot->info)
continue;
if (slot->hotplug_slot->info->adapter_status == 0)
continue;
/* If another adapter is running on the same segment but at a
* lower speed/mode, we allow the new adapter to function at
* this rate if supported */
if (ctrl->speed < adapter_speed)
return 0;
return 1;
}
/* If the controller doesn't support freq/mode changes and the
* controller is running at a higher mode, we bail */
if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability))
return 1;
/* But we allow the adapter to run at a lower rate if possible */
if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability))
return 0;
/* We try to set the max speed supported by both the adapter and
* controller */
if (ctrl->speed_capability < adapter_speed) {
if (ctrl->speed == ctrl->speed_capability)
return 0;
adapter_speed = ctrl->speed_capability;
}
writel(0x0L, ctrl->hpc_reg + LED_CONTROL);
writeb(0x00, ctrl->hpc_reg + SLOT_ENABLE);
set_SOGO(ctrl);
wait_for_ctrl_irq(ctrl);
if (adapter_speed != PCI_SPEED_133MHz_PCIX)
reg = 0xF5;
else
reg = 0xF4;
pci_write_config_byte(ctrl->pci_dev, 0x41, reg);
reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ);
reg16 &= ~0x000F;
switch(adapter_speed) {
case(PCI_SPEED_133MHz_PCIX):
reg = 0x75;
reg16 |= 0xB;
break;
case(PCI_SPEED_100MHz_PCIX):
reg = 0x74;
reg16 |= 0xA;
break;
case(PCI_SPEED_66MHz_PCIX):
reg = 0x73;
reg16 |= 0x9;
break;
case(PCI_SPEED_66MHz):
reg = 0x73;
reg16 |= 0x1;
break;
default: /* 33MHz PCI 2.2 */
reg = 0x71;
break;
}
reg16 |= 0xB << 12;
writew(reg16, ctrl->hpc_reg + NEXT_CURR_FREQ);
mdelay(5);
/* Reenable interrupts */
writel(0, ctrl->hpc_reg + INT_MASK);
pci_write_config_byte(ctrl->pci_dev, 0x41, reg);
/* Restart state machine */
reg = ~0xF;
pci_read_config_byte(ctrl->pci_dev, 0x43, &reg);
pci_write_config_byte(ctrl->pci_dev, 0x43, reg);
/* Only if mode change...*/
if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) ||
((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz)))
set_SOGO(ctrl);
wait_for_ctrl_irq(ctrl);
mdelay(1100);
/* Restore LED/Slot state */
writel(leds, ctrl->hpc_reg + LED_CONTROL);
writeb(slot_power, ctrl->hpc_reg + SLOT_ENABLE);
set_SOGO(ctrl);
wait_for_ctrl_irq(ctrl);
ctrl->speed = adapter_speed;
slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
info("Successfully changed frequency/mode for adapter in slot %d\n",
slot->number);
return 0;
}
#endif #endif
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
* *
* Send feedback to <greg@kroah.com> * Send feedback to <greg@kroah.com>
* *
* Jan 12, 2003 - Added 66/100/133MHz PCI-X support,
* Torben Mathiasen <torben.mathiasen@hp.com>
*
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -57,7 +60,7 @@ static void *cpqhp_rom_start; ...@@ -57,7 +60,7 @@ static void *cpqhp_rom_start;
static u8 power_mode; static u8 power_mode;
static int debug; static int debug;
#define DRIVER_VERSION "0.9.6" #define DRIVER_VERSION "0.9.7"
#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>" #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"
#define DRIVER_DESC "Compaq Hot Plug PCI Controller Driver" #define DRIVER_DESC "Compaq Hot Plug PCI Controller Driver"
...@@ -835,6 +838,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -835,6 +838,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
u8 hp_slot = 0; u8 hp_slot = 0;
u8 device; u8 device;
u8 rev; u8 rev;
u8 bus_cap;
u16 temp_word; u16 temp_word;
u16 vendor_id; u16 vendor_id;
u16 subsystem_vid; u16 subsystem_vid;
...@@ -896,6 +900,39 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -896,6 +900,39 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
switch (subsystem_vid) { switch (subsystem_vid) {
case PCI_VENDOR_ID_COMPAQ: case PCI_VENDOR_ID_COMPAQ:
if (rev >= 0x13) { /* CIOBX */
ctrl->push_flag = 1;
ctrl->slot_switch_type = 1; // Switch is present
ctrl->push_button = 1; // Pushbutton is present
ctrl->pci_config_space = 1; // Index/data access to working registers 0 = not supported, 1 = supported
ctrl->defeature_PHP = 1; // PHP is supported
ctrl->pcix_support = 1; // PCI-X supported
ctrl->pcix_speed_capability = 1;
pci_read_config_byte(pdev, 0x41, &bus_cap);
if (bus_cap & 0x80) {
dbg("bus max supports 133MHz PCI-X\n");
ctrl->speed_capability = PCI_SPEED_133MHz_PCIX;
break;
}
if (bus_cap & 0x40) {
dbg("bus max supports 100MHz PCI-X\n");
ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
break;
}
if (bus_cap & 20) {
dbg("bus max supports 66MHz PCI-X\n");
ctrl->speed_capability = PCI_SPEED_66MHz_PCIX;
break;
}
if (bus_cap & 10) {
dbg("bus max supports 66MHz PCI\n");
ctrl->speed_capability = PCI_SPEED_66MHz;
break;
}
break;
}
switch (subsystem_deviceid) { switch (subsystem_deviceid) {
case PCI_SUB_HPC_ID: case PCI_SUB_HPC_ID:
/* Original 6500/7000 implementation */ /* Original 6500/7000 implementation */
...@@ -939,8 +976,18 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -939,8 +976,18 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ctrl->pcix_support = 0; // PCI-X not supported ctrl->pcix_support = 0; // PCI-X not supported
ctrl->pcix_speed_capability = 0; // N/A since PCI-X not supported ctrl->pcix_speed_capability = 0; // N/A since PCI-X not supported
break; break;
case PCI_SUB_HPC_ID4:
/* First PCI-X implementation, 100MHz */
ctrl->push_flag = 1;
ctrl->slot_switch_type = 1; // Switch is present
ctrl->speed_capability = PCI_SPEED_100MHz_PCIX;
ctrl->push_button = 1; // Pushbutton is present
ctrl->pci_config_space = 1; // Index/data access to working registers 0 = not supported, 1 = supported
ctrl->defeature_PHP = 1; // PHP is supported
ctrl->pcix_support = 1; // PCI-X supported
ctrl->pcix_speed_capability = 0;
break;
default: default:
// TODO: Add SSIDs for CPQ systems that support PCI-X
err(msg_HPC_not_supported); err(msg_HPC_not_supported);
rc = -ENODEV; rc = -ENODEV;
goto err_free_ctrl; goto err_free_ctrl;
...@@ -1029,7 +1076,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1029,7 +1076,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
info("Initializing the PCI hot plug controller residing on PCI bus %d\n", pdev->bus->number); info("Initializing the PCI hot plug controller residing on PCI bus %d\n", pdev->bus->number);
dbg ("Hotplug controller capabilities:\n"); dbg ("Hotplug controller capabilities:\n");
dbg (" speed_capability %s\n", ctrl->speed_capability == PCI_SPEED_33MHz ? "33MHz" : "66Mhz"); dbg (" speed_capability %d\n", ctrl->speed_capability);
dbg (" slot_switch_type %s\n", ctrl->slot_switch_type == 0 ? "no switch" : "switch present"); dbg (" slot_switch_type %s\n", ctrl->slot_switch_type == 0 ? "no switch" : "switch present");
dbg (" defeature_PHP %s\n", ctrl->defeature_PHP == 0 ? "PHP not supported" : "PHP supported"); dbg (" defeature_PHP %s\n", ctrl->defeature_PHP == 0 ? "PHP not supported" : "PHP supported");
dbg (" alternate_base_address %s\n", ctrl->alternate_base_address == 0 ? "not supported" : "supported"); dbg (" alternate_base_address %s\n", ctrl->alternate_base_address == 0 ? "not supported" : "supported");
...@@ -1082,7 +1129,6 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1082,7 +1129,6 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
} }
// Check for 66Mhz operation // Check for 66Mhz operation
// TODO: Add PCI-X support
ctrl->speed = get_controller_speed(ctrl); ctrl->speed = get_controller_speed(ctrl);
...@@ -1119,6 +1165,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1119,6 +1165,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
// The next line is required for cpqhp_find_available_resources // The next line is required for cpqhp_find_available_resources
ctrl->interrupt = pdev->irq; ctrl->interrupt = pdev->irq;
ctrl->cfgspc_irq = 0;
pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &ctrl->cfgspc_irq);
rc = cpqhp_find_available_resources(ctrl, cpqhp_rom_start); rc = cpqhp_find_available_resources(ctrl, cpqhp_rom_start);
ctrl->add_support = !rc; ctrl->add_support = !rc;
if (rc) { if (rc) {
......
...@@ -136,9 +136,9 @@ static u8 handle_switch_change(u8 change, struct controller * ctrl) ...@@ -136,9 +136,9 @@ static u8 handle_switch_change(u8 change, struct controller * ctrl)
/* /*
* find_slot * cpqhp_find_slot
*/ */
static inline struct slot *find_slot (struct controller * ctrl, u8 device) struct slot *cpqhp_find_slot (struct controller * ctrl, u8 device)
{ {
struct slot *slot; struct slot *slot;
...@@ -187,7 +187,7 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl) ...@@ -187,7 +187,7 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl)
rc++; rc++;
p_slot = find_slot(ctrl, hp_slot + (readb(ctrl->hpc_reg + SLOT_MASK) >> 4)); p_slot = cpqhp_find_slot(ctrl, hp_slot + (readb(ctrl->hpc_reg + SLOT_MASK) >> 4));
if (!p_slot) if (!p_slot)
return 0; return 0;
...@@ -920,6 +920,7 @@ irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data, struct pt_regs *regs) ...@@ -920,6 +920,7 @@ irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data, struct pt_regs *regs)
{ {
struct controller *ctrl = data; struct controller *ctrl = data;
u8 schedule_flag = 0; u8 schedule_flag = 0;
u8 reset;
u16 misc; u16 misc;
u32 Diff; u32 Diff;
u32 temp_dword; u32 temp_dword;
...@@ -971,6 +972,15 @@ irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data, struct pt_regs *regs) ...@@ -971,6 +972,15 @@ irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data, struct pt_regs *regs)
schedule_flag += handle_power_fault((u8)((Diff & 0xFF00L) >> 8), ctrl); schedule_flag += handle_power_fault((u8)((Diff & 0xFF00L) >> 8), ctrl);
} }
reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
if (reset & 0x40) {
/* Bus reset has completed */
reset &= 0xCF;
writeb(reset, ctrl->hpc_reg + RESET_FREQ_MODE);
reset = readb(ctrl->hpc_reg + RESET_FREQ_MODE);
wake_up_interruptible(&ctrl->queue);
}
if (schedule_flag) { if (schedule_flag) {
up(&event_semaphore); up(&event_semaphore);
dbg("Signal event_semaphore\n"); dbg("Signal event_semaphore\n");
...@@ -1172,6 +1182,7 @@ static u32 board_replaced(struct pci_func * func, struct controller * ctrl) ...@@ -1172,6 +1182,7 @@ static u32 board_replaced(struct pci_func * func, struct controller * ctrl)
{ {
u8 hp_slot; u8 hp_slot;
u8 temp_byte; u8 temp_byte;
u8 adapter_speed;
u32 index; u32 index;
u32 rc = 0; u32 rc = 0;
u32 src = 8; u32 src = 8;
...@@ -1189,7 +1200,6 @@ static u32 board_replaced(struct pci_func * func, struct controller * ctrl) ...@@ -1189,7 +1200,6 @@ static u32 board_replaced(struct pci_func * func, struct controller * ctrl)
//********************************* //*********************************
rc = CARD_FUNCTIONING; rc = CARD_FUNCTIONING;
} else { } else {
if (ctrl->speed == PCI_SPEED_66MHz) {
// Wait for exclusive access to hardware // Wait for exclusive access to hardware
down(&ctrl->crit_sect); down(&ctrl->crit_sect);
...@@ -1212,9 +1222,11 @@ static u32 board_replaced(struct pci_func * func, struct controller * ctrl) ...@@ -1212,9 +1222,11 @@ static u32 board_replaced(struct pci_func * func, struct controller * ctrl)
// Wait for SOBS to be unset // Wait for SOBS to be unset
wait_for_ctrl_irq (ctrl); wait_for_ctrl_irq (ctrl);
if (!(readl(ctrl->hpc_reg + NON_INT_INPUT) & (0x01 << hp_slot))) { adapter_speed = get_adapter_speed(ctrl, hp_slot);
if (ctrl->speed != adapter_speed)
if (set_controller_speed(ctrl, adapter_speed, hp_slot))
rc = WRONG_BUS_FREQUENCY; rc = WRONG_BUS_FREQUENCY;
}
// turn off board without attaching to the bus // turn off board without attaching to the bus
disable_slot_power (ctrl, hp_slot); disable_slot_power (ctrl, hp_slot);
...@@ -1228,7 +1240,6 @@ static u32 board_replaced(struct pci_func * func, struct controller * ctrl) ...@@ -1228,7 +1240,6 @@ static u32 board_replaced(struct pci_func * func, struct controller * ctrl)
if (rc) if (rc)
return(rc); return(rc);
}
// Wait for exclusive access to hardware // Wait for exclusive access to hardware
down(&ctrl->crit_sect); down(&ctrl->crit_sect);
...@@ -1376,6 +1387,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) ...@@ -1376,6 +1387,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
{ {
u8 hp_slot; u8 hp_slot;
u8 temp_byte; u8 temp_byte;
u8 adapter_speed;
int index; int index;
u32 temp_register = 0xFFFFFFFF; u32 temp_register = 0xFFFFFFFF;
u32 rc = 0; u32 rc = 0;
...@@ -1387,7 +1399,6 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) ...@@ -1387,7 +1399,6 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n",
__FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot); __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
if (ctrl->speed == PCI_SPEED_66MHz) {
// Wait for exclusive access to hardware // Wait for exclusive access to hardware
down(&ctrl->crit_sect); down(&ctrl->crit_sect);
...@@ -1410,9 +1421,11 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) ...@@ -1410,9 +1421,11 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
// Wait for SOBS to be unset // Wait for SOBS to be unset
wait_for_ctrl_irq (ctrl); wait_for_ctrl_irq (ctrl);
if (!(readl(ctrl->hpc_reg + NON_INT_INPUT) & (0x01 << hp_slot))) { adapter_speed = get_adapter_speed(ctrl, hp_slot);
if (ctrl->speed != adapter_speed)
if (set_controller_speed(ctrl, adapter_speed, hp_slot))
rc = WRONG_BUS_FREQUENCY; rc = WRONG_BUS_FREQUENCY;
}
// turn off board without attaching to the bus // turn off board without attaching to the bus
disable_slot_power (ctrl, hp_slot); disable_slot_power (ctrl, hp_slot);
...@@ -1426,8 +1439,8 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) ...@@ -1426,8 +1439,8 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
if (rc) if (rc)
return(rc); return(rc);
}
p_slot = find_slot(ctrl, hp_slot + ctrl->slot_device_offset); p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
// turn on board and blink green LED // turn on board and blink green LED
...@@ -1800,7 +1813,7 @@ static void interrupt_event_handler(struct controller *ctrl) ...@@ -1800,7 +1813,7 @@ static void interrupt_event_handler(struct controller *ctrl)
if (!func) if (!func)
return; return;
p_slot = find_slot(ctrl, hp_slot + ctrl->slot_device_offset); p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
if (!p_slot) if (!p_slot)
return; return;
...@@ -1862,6 +1875,7 @@ static void interrupt_event_handler(struct controller *ctrl) ...@@ -1862,6 +1875,7 @@ static void interrupt_event_handler(struct controller *ctrl)
down(&ctrl->crit_sect); down(&ctrl->crit_sect);
dbg("blink green LED and turn off amber\n"); dbg("blink green LED and turn off amber\n");
amber_LED_off (ctrl, hp_slot); amber_LED_off (ctrl, hp_slot);
green_LED_blink (ctrl, hp_slot); green_LED_blink (ctrl, hp_slot);
...@@ -1992,7 +2006,7 @@ int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func) ...@@ -1992,7 +2006,7 @@ int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func)
device = func->device; device = func->device;
hp_slot = device - ctrl->slot_device_offset; hp_slot = device - ctrl->slot_device_offset;
p_slot = find_slot(ctrl, device); p_slot = cpqhp_find_slot(ctrl, device);
if (p_slot) { if (p_slot) {
physical_slot = p_slot->number; physical_slot = p_slot->number;
} }
...@@ -2091,7 +2105,7 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func) ...@@ -2091,7 +2105,7 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
device = func->device; device = func->device;
func = cpqhp_slot_find(ctrl->bus, device, index++); func = cpqhp_slot_find(ctrl->bus, device, index++);
p_slot = find_slot(ctrl, device); p_slot = cpqhp_find_slot(ctrl, device);
if (p_slot) { if (p_slot) {
physical_slot = p_slot->number; physical_slot = p_slot->number;
} }
......
...@@ -85,18 +85,20 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) ...@@ -85,18 +85,20 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
{ {
unsigned char bus; unsigned char bus;
struct pci_bus *child; struct pci_bus *child;
int rc = 0; int num;
if (func->pci_dev == NULL) if (func->pci_dev == NULL)
func->pci_dev = pci_find_slot(func->bus, (func->device << 3) | (func->function & 0x7)); func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
//Still NULL ? Well then scan for it ! /* No pci device, we need to create it then */
if (func->pci_dev == NULL) { if (func->pci_dev == NULL) {
dbg("INFO: pci_dev still null\n"); dbg("INFO: pci_dev still null\n");
//this will generate pci_dev structures for all functions, but we will only call this case when lookup fails num = pci_scan_slot(ctrl->pci_dev->bus, PCI_DEVFN(func->device, func->function));
func->pci_dev = pci_scan_slot(ctrl->pci_dev->bus, if (num)
(func->device << 3) + (func->function & 0x7)); pci_bus_add_devices(ctrl->pci_dev->bus);
func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
if (func->pci_dev == NULL) { if (func->pci_dev == NULL) {
dbg("ERROR: pci_dev still null\n"); dbg("ERROR: pci_dev still null\n");
return 0; return 0;
...@@ -107,10 +109,9 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) ...@@ -107,10 +109,9 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus); pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus);
child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus); child = (struct pci_bus*) pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus);
pci_do_scan_bus(child); pci_do_scan_bus(child);
} }
return rc; return 0;
} }
...@@ -1209,11 +1210,11 @@ int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start) ...@@ -1209,11 +1210,11 @@ int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start)
temp = 0; temp = 0;
if (!cpqhp_nic_irq) { if (!cpqhp_nic_irq) {
cpqhp_nic_irq = ctrl->interrupt; cpqhp_nic_irq = ctrl->cfgspc_irq;
} }
if (!cpqhp_disk_irq) { if (!cpqhp_disk_irq) {
cpqhp_disk_irq = ctrl->interrupt; cpqhp_disk_irq = ctrl->cfgspc_irq;
} }
dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq); dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq);
......
...@@ -846,22 +846,24 @@ static int ibm_configure_device (struct pci_func *func) ...@@ -846,22 +846,24 @@ static int ibm_configure_device (struct pci_func *func)
{ {
unsigned char bus; unsigned char bus;
struct pci_bus *child; struct pci_bus *child;
int rc = 0; int num;
int flag = 0; /* this is to make sure we don't double scan the bus, for bridged devices primarily */ int flag = 0; /* this is to make sure we don't double scan the bus, for bridged devices primarily */
if (!(bus_structure_fixup (func->busno))) if (!(bus_structure_fixup (func->busno)))
flag = 1; flag = 1;
if (func->dev == NULL) if (func->dev == NULL)
func->dev = pci_find_slot (func->busno, (func->device << 3) | (func->function & 0x7)); func->dev = pci_find_slot (func->busno, PCI_DEVFN(func->device, func->function));
if (func->dev == NULL) { if (func->dev == NULL) {
struct pci_bus *bus = ibmphp_find_bus (func->busno); struct pci_bus *bus = ibmphp_find_bus (func->busno);
if (!bus) if (!bus)
return 0; return 0;
func->dev = pci_scan_slot(bus, num = pci_scan_slot(bus, PCI_DEVFN(func->device, func->function));
(func->device << 3) + (func->function & 0x7)); if (num)
pci_bus_add_devices(bus);
func->dev = pci_find_slot(func->busno, PCI_DEVFN(func->device, func->function));
if (func->dev == NULL) { if (func->dev == NULL) {
err ("ERROR... : pci_dev still NULL \n"); err ("ERROR... : pci_dev still NULL \n");
return 0; return 0;
...@@ -873,7 +875,7 @@ static int ibm_configure_device (struct pci_func *func) ...@@ -873,7 +875,7 @@ static int ibm_configure_device (struct pci_func *func)
pci_do_scan_bus (child); pci_do_scan_bus (child);
} }
return rc; return 0;
} }
/******************************************************* /*******************************************************
...@@ -1415,7 +1417,7 @@ static int __init ibmphp_init (void) ...@@ -1415,7 +1417,7 @@ static int __init ibmphp_init (void)
/* lock ourselves into memory with a module /* lock ourselves into memory with a module
* count of -1 so that no one can unload us. */ * count of -1 so that no one can unload us. */
MOD_DEC_USE_COUNT; module_put(THIS_MODULE);
exit: exit:
return rc; return rc;
......
...@@ -475,6 +475,7 @@ static struct i2c_algorithm smbus_algorithm = { ...@@ -475,6 +475,7 @@ static struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter ali15x3_adapter = { static struct i2c_adapter ali15x3_adapter = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_ALI15X3, .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_ALI15X3,
.class = I2C_ADAP_CLASS_SMBUS,
.algo = &smbus_algorithm, .algo = &smbus_algorithm,
.dev = { .dev = {
.name = "unset", .name = "unset",
......
...@@ -313,6 +313,7 @@ static struct i2c_algorithm smbus_algorithm = { ...@@ -313,6 +313,7 @@ static struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter amd756_adapter = { static struct i2c_adapter amd756_adapter = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_AMD756, .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_AMD756,
.class = I2C_ADAP_CLASS_SMBUS,
.algo = &smbus_algorithm, .algo = &smbus_algorithm,
.dev = { .dev = {
.name = "unset", .name = "unset",
......
...@@ -360,6 +360,7 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_ ...@@ -360,6 +360,7 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_
snprintf(smbus->adapter.dev.name, DEVICE_NAME_SIZE, snprintf(smbus->adapter.dev.name, DEVICE_NAME_SIZE,
"SMBus2 AMD8111 adapter at %04x", smbus->base); "SMBus2 AMD8111 adapter at %04x", smbus->base);
smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_AMD8111; smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_AMD8111;
smbus->adapter.class = I2C_ADAP_CLASS_SMBUS;
smbus->adapter.algo = &smbus_algorithm; smbus->adapter.algo = &smbus_algorithm;
smbus->adapter.algo_data = smbus; smbus->adapter.algo_data = smbus;
......
...@@ -547,6 +547,7 @@ static struct i2c_algorithm smbus_algorithm = { ...@@ -547,6 +547,7 @@ static struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter i801_adapter = { static struct i2c_adapter i801_adapter = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_I801, .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_I801,
.class = I2C_ADAP_CLASS_SMBUS,
.algo = &smbus_algorithm, .algo = &smbus_algorithm,
.dev = { .dev = {
.name = "unset", .name = "unset",
......
...@@ -40,6 +40,7 @@ static struct i2c_algorithm isa_algorithm = { ...@@ -40,6 +40,7 @@ static struct i2c_algorithm isa_algorithm = {
static struct i2c_adapter isa_adapter = { static struct i2c_adapter isa_adapter = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.id = I2C_ALGO_ISA | I2C_HW_ISA, .id = I2C_ALGO_ISA | I2C_HW_ISA,
.class = I2C_ADAP_CLASS_SMBUS,
.algo = &isa_algorithm, .algo = &isa_algorithm,
.dev = { .dev = {
.name = "ISA main adapter", .name = "ISA main adapter",
......
...@@ -395,6 +395,7 @@ static struct i2c_algorithm smbus_algorithm = { ...@@ -395,6 +395,7 @@ static struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter piix4_adapter = { static struct i2c_adapter piix4_adapter = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_PIIX4, .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_PIIX4,
.class = I2C_ADAP_CLASS_SMBUS,
.algo = &smbus_algorithm, .algo = &smbus_algorithm,
.dev = { .dev = {
.name = "unset", .name = "unset",
......
...@@ -295,6 +295,7 @@ static struct i2c_algorithm smbus_algorithm = { ...@@ -295,6 +295,7 @@ static struct i2c_algorithm smbus_algorithm = {
static struct i2c_adapter vt596_adapter = { static struct i2c_adapter vt596_adapter = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_VIA2, .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_VIA2,
.class = I2C_ADAP_CLASS_SMBUS,
.algo = &smbus_algorithm, .algo = &smbus_algorithm,
.dev = { .dev = {
.name = "unset", .name = "unset",
......
...@@ -203,6 +203,8 @@ static DEVICE_ATTR(die_code, S_IRUGO, show_die_code, NULL); ...@@ -203,6 +203,8 @@ static DEVICE_ATTR(die_code, S_IRUGO, show_die_code, NULL);
static int adm1021_attach_adapter(struct i2c_adapter *adapter) static int adm1021_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_ADAP_CLASS_SMBUS))
return 0;
return i2c_detect(adapter, &addr_data, adm1021_detect); return i2c_detect(adapter, &addr_data, adm1021_detect);
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
monitoring. monitoring.
Supports: IT8705F Super I/O chip w/LPC interface Supports: IT8705F Super I/O chip w/LPC interface
IT8712F Super I/O chup w/LPC interface & SMbus IT8712F Super I/O chip w/LPC interface & SMbus
Sis950 A clone of the IT8705F Sis950 A clone of the IT8705F
Copyright (c) 2001 Chris Gauthron <chrisg@0-in.com> Copyright (c) 2001 Chris Gauthron <chrisg@0-in.com>
...@@ -238,6 +238,7 @@ struct it87_data { ...@@ -238,6 +238,7 @@ struct it87_data {
u8 temp[3]; /* Register value */ u8 temp[3]; /* Register value */
u8 temp_high[3]; /* Register value */ u8 temp_high[3]; /* Register value */
u8 temp_low[3]; /* Register value */ u8 temp_low[3]; /* Register value */
u8 sensor; /* Register value */
u8 fan_div[3]; /* Register encoding, shifted right */ u8 fan_div[3]; /* Register encoding, shifted right */
u8 vid; /* Register encoding, combined */ u8 vid; /* Register encoding, combined */
u32 alarms; /* Register encoding, combined */ u32 alarms; /* Register encoding, combined */
...@@ -252,7 +253,7 @@ static int it87_read_value(struct i2c_client *client, u8 register); ...@@ -252,7 +253,7 @@ static int it87_read_value(struct i2c_client *client, u8 register);
static int it87_write_value(struct i2c_client *client, u8 register, static int it87_write_value(struct i2c_client *client, u8 register,
u8 value); u8 value);
static void it87_update_client(struct i2c_client *client); static void it87_update_client(struct i2c_client *client);
static void it87_init_client(struct i2c_client *client); static void it87_init_client(struct i2c_client *client, struct it87_data *data);
static struct i2c_driver it87_driver = { static struct i2c_driver it87_driver = {
...@@ -350,6 +351,10 @@ show_in_offset(1); ...@@ -350,6 +351,10 @@ show_in_offset(1);
show_in_offset(2); show_in_offset(2);
show_in_offset(3); show_in_offset(3);
show_in_offset(4); show_in_offset(4);
show_in_offset(5);
show_in_offset(6);
show_in_offset(7);
show_in_offset(8);
/* 3 temperatures */ /* 3 temperatures */
static ssize_t show_temp(struct device *dev, char *buf, int nr) static ssize_t show_temp(struct device *dev, char *buf, int nr)
...@@ -430,7 +435,52 @@ show_temp_offset(1); ...@@ -430,7 +435,52 @@ show_temp_offset(1);
show_temp_offset(2); show_temp_offset(2);
show_temp_offset(3); show_temp_offset(3);
/* 2 Fans */ /* more like overshoot temperature */
static ssize_t show_sensor(struct device *dev, char *buf, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
it87_update_client(client);
if (data->sensor & (1 << nr))
return sprintf(buf, "1\n");
if (data->sensor & (8 << nr))
return sprintf(buf, "2\n");
return sprintf(buf, "0\n");
}
static ssize_t set_sensor(struct device *dev, const char *buf,
size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
data->sensor &= ~(1 << nr);
data->sensor &= ~(8 << nr);
if (val == 1)
data->sensor |= 1 << nr;
else if (val == 2)
data->sensor |= 8 << nr;
it87_write_value(client, IT87_REG_TEMP_ENABLE, data->sensor);
return count;
}
#define show_sensor_offset(offset) \
static ssize_t show_sensor_##offset (struct device *dev, char *buf) \
{ \
return show_sensor(dev, buf, 0x##offset - 1); \
} \
static ssize_t set_sensor_##offset (struct device *dev, \
const char *buf, size_t count) \
{ \
return set_sensor(dev, buf, count, 0x##offset - 1); \
} \
static DEVICE_ATTR(sensor##offset, S_IRUGO | S_IWUSR, \
show_sensor_##offset, set_sensor_##offset)
show_sensor_offset(1);
show_sensor_offset(2);
show_sensor_offset(3);
/* 3 Fans */
static ssize_t show_fan(struct device *dev, char *buf, int nr) static ssize_t show_fan(struct device *dev, char *buf, int nr)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
...@@ -508,6 +558,7 @@ static DEVICE_ATTR(fan_div##offset, S_IRUGO | S_IWUSR, \ ...@@ -508,6 +558,7 @@ static DEVICE_ATTR(fan_div##offset, S_IRUGO | S_IWUSR, \
show_fan_offset(1); show_fan_offset(1);
show_fan_offset(2); show_fan_offset(2);
show_fan_offset(3);
/* Alarm */ /* Alarm */
static ssize_t show_alarm(struct device *dev, char *buf) static ssize_t show_alarm(struct device *dev, char *buf)
...@@ -525,6 +576,8 @@ static DEVICE_ATTR(alarm, S_IRUGO | S_IWUSR, show_alarm, NULL); ...@@ -525,6 +576,8 @@ static DEVICE_ATTR(alarm, S_IRUGO | S_IWUSR, show_alarm, NULL);
* when a new adapter is inserted (and it87_driver is still present) */ * when a new adapter is inserted (and it87_driver is still present) */
static int it87_attach_adapter(struct i2c_adapter *adapter) static int it87_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_ADAP_CLASS_SMBUS))
return 0;
return i2c_detect(adapter, &addr_data, it87_detect); return i2c_detect(adapter, &addr_data, it87_detect);
} }
...@@ -574,6 +627,7 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -574,6 +627,7 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
} }
} }
} }
memset (new_client, 0x00, sizeof(struct i2c_client) + sizeof(struct it87_data));
/* OK. For now, we presume we have a valid client. We now create the /* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet. client structure, even though we cannot fill it completely yet.
...@@ -585,6 +639,8 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -585,6 +639,8 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
err = -ENOMEM; err = -ENOMEM;
goto ERROR1; goto ERROR1;
} }
memset(new_client, 0x00, sizeof(struct i2c_client) +
sizeof(struct it87_data));
data = (struct it87_data *) (new_client + 1); data = (struct it87_data *) (new_client + 1);
if (is_isa) if (is_isa)
...@@ -652,16 +708,28 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -652,16 +708,28 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file(&new_client->dev, &dev_attr_in_input2); device_create_file(&new_client->dev, &dev_attr_in_input2);
device_create_file(&new_client->dev, &dev_attr_in_input3); device_create_file(&new_client->dev, &dev_attr_in_input3);
device_create_file(&new_client->dev, &dev_attr_in_input4); device_create_file(&new_client->dev, &dev_attr_in_input4);
device_create_file(&new_client->dev, &dev_attr_in_input5);
device_create_file(&new_client->dev, &dev_attr_in_input6);
device_create_file(&new_client->dev, &dev_attr_in_input7);
device_create_file(&new_client->dev, &dev_attr_in_input8);
device_create_file(&new_client->dev, &dev_attr_in_min0); device_create_file(&new_client->dev, &dev_attr_in_min0);
device_create_file(&new_client->dev, &dev_attr_in_min1); device_create_file(&new_client->dev, &dev_attr_in_min1);
device_create_file(&new_client->dev, &dev_attr_in_min2); device_create_file(&new_client->dev, &dev_attr_in_min2);
device_create_file(&new_client->dev, &dev_attr_in_min3); device_create_file(&new_client->dev, &dev_attr_in_min3);
device_create_file(&new_client->dev, &dev_attr_in_min4); device_create_file(&new_client->dev, &dev_attr_in_min4);
device_create_file(&new_client->dev, &dev_attr_in_min5);
device_create_file(&new_client->dev, &dev_attr_in_min6);
device_create_file(&new_client->dev, &dev_attr_in_min7);
device_create_file(&new_client->dev, &dev_attr_in_min8);
device_create_file(&new_client->dev, &dev_attr_in_max0); device_create_file(&new_client->dev, &dev_attr_in_max0);
device_create_file(&new_client->dev, &dev_attr_in_max1); device_create_file(&new_client->dev, &dev_attr_in_max1);
device_create_file(&new_client->dev, &dev_attr_in_max2); device_create_file(&new_client->dev, &dev_attr_in_max2);
device_create_file(&new_client->dev, &dev_attr_in_max3); device_create_file(&new_client->dev, &dev_attr_in_max3);
device_create_file(&new_client->dev, &dev_attr_in_max4); device_create_file(&new_client->dev, &dev_attr_in_max4);
device_create_file(&new_client->dev, &dev_attr_in_max5);
device_create_file(&new_client->dev, &dev_attr_in_max6);
device_create_file(&new_client->dev, &dev_attr_in_max7);
device_create_file(&new_client->dev, &dev_attr_in_max8);
device_create_file(&new_client->dev, &dev_attr_temp_input1); device_create_file(&new_client->dev, &dev_attr_temp_input1);
device_create_file(&new_client->dev, &dev_attr_temp_input2); device_create_file(&new_client->dev, &dev_attr_temp_input2);
device_create_file(&new_client->dev, &dev_attr_temp_input3); device_create_file(&new_client->dev, &dev_attr_temp_input3);
...@@ -671,16 +739,22 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -671,16 +739,22 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind)
device_create_file(&new_client->dev, &dev_attr_temp_min1); device_create_file(&new_client->dev, &dev_attr_temp_min1);
device_create_file(&new_client->dev, &dev_attr_temp_min2); device_create_file(&new_client->dev, &dev_attr_temp_min2);
device_create_file(&new_client->dev, &dev_attr_temp_min3); device_create_file(&new_client->dev, &dev_attr_temp_min3);
device_create_file(&new_client->dev, &dev_attr_sensor1);
device_create_file(&new_client->dev, &dev_attr_sensor2);
device_create_file(&new_client->dev, &dev_attr_sensor3);
device_create_file(&new_client->dev, &dev_attr_fan_input1); device_create_file(&new_client->dev, &dev_attr_fan_input1);
device_create_file(&new_client->dev, &dev_attr_fan_input2); device_create_file(&new_client->dev, &dev_attr_fan_input2);
device_create_file(&new_client->dev, &dev_attr_fan_input3);
device_create_file(&new_client->dev, &dev_attr_fan_min1); device_create_file(&new_client->dev, &dev_attr_fan_min1);
device_create_file(&new_client->dev, &dev_attr_fan_min2); device_create_file(&new_client->dev, &dev_attr_fan_min2);
device_create_file(&new_client->dev, &dev_attr_fan_min3);
device_create_file(&new_client->dev, &dev_attr_fan_div1); device_create_file(&new_client->dev, &dev_attr_fan_div1);
device_create_file(&new_client->dev, &dev_attr_fan_div2); device_create_file(&new_client->dev, &dev_attr_fan_div2);
device_create_file(&new_client->dev, &dev_attr_fan_div3);
device_create_file(&new_client->dev, &dev_attr_alarm); device_create_file(&new_client->dev, &dev_attr_alarm);
/* Initialize the IT87 chip */ /* Initialize the IT87 chip */
it87_init_client(new_client); it87_init_client(new_client, data);
return 0; return 0;
ERROR1: ERROR1:
...@@ -753,7 +827,7 @@ static int it87_write_value(struct i2c_client *client, u8 reg, u8 value) ...@@ -753,7 +827,7 @@ static int it87_write_value(struct i2c_client *client, u8 reg, u8 value)
} }
/* Called when we have found a new IT87. It should set limits, etc. */ /* Called when we have found a new IT87. It should set limits, etc. */
static void it87_init_client(struct i2c_client *client) static void it87_init_client(struct i2c_client *client, struct it87_data *data)
{ {
/* Reset all except Watchdog values and last conversion values /* Reset all except Watchdog values and last conversion values
This sets fan-divs to 2, among others */ This sets fan-divs to 2, among others */
...@@ -814,9 +888,9 @@ static void it87_init_client(struct i2c_client *client) ...@@ -814,9 +888,9 @@ static void it87_init_client(struct i2c_client *client)
it87_write_value(client, IT87_REG_VIN_ENABLE, 0xff); it87_write_value(client, IT87_REG_VIN_ENABLE, 0xff);
/* Enable Temp1-Temp3 */ /* Enable Temp1-Temp3 */
it87_write_value(client, IT87_REG_TEMP_ENABLE, data->sensor = (it87_read_value(client, IT87_REG_TEMP_ENABLE) & 0xc0);
(it87_read_value(client, IT87_REG_TEMP_ENABLE) & 0xc0) data->sensor |= temp_type & 0x3f;
| (temp_type & 0x3f)); it87_write_value(client, IT87_REG_TEMP_ENABLE, data->sensor);
/* Enable fans */ /* Enable fans */
it87_write_value(client, IT87_REG_FAN_CTRL, it87_write_value(client, IT87_REG_FAN_CTRL,
......
...@@ -121,6 +121,8 @@ static DEVICE_ATTR(temp_input, S_IRUGO, show_temp_input, NULL); ...@@ -121,6 +121,8 @@ static DEVICE_ATTR(temp_input, S_IRUGO, show_temp_input, NULL);
static int lm75_attach_adapter(struct i2c_adapter *adapter) static int lm75_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_ADAP_CLASS_SMBUS))
return 0;
return i2c_detect(adapter, &addr_data, lm75_detect); return i2c_detect(adapter, &addr_data, lm75_detect);
} }
......
...@@ -661,6 +661,8 @@ static struct i2c_driver via686a_driver = { ...@@ -661,6 +661,8 @@ static struct i2c_driver via686a_driver = {
/* This is called when the module is loaded */ /* This is called when the module is loaded */
static int via686a_attach_adapter(struct i2c_adapter *adapter) static int via686a_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_ADAP_CLASS_SMBUS))
return 0;
return i2c_detect(adapter, &addr_data, via686a_detect); return i2c_detect(adapter, &addr_data, via686a_detect);
} }
......
...@@ -1026,6 +1026,8 @@ device_create_file(&client->dev, &dev_attr_rt##offset); \ ...@@ -1026,6 +1026,8 @@ device_create_file(&client->dev, &dev_attr_rt##offset); \
static int static int
w83781d_attach_adapter(struct i2c_adapter *adapter) w83781d_attach_adapter(struct i2c_adapter *adapter)
{ {
if (!(adapter->class & I2C_ADAP_CLASS_SMBUS))
return 0;
return i2c_detect(adapter, &addr_data, w83781d_detect); return i2c_detect(adapter, &addr_data, w83781d_detect);
} }
......
...@@ -38,8 +38,8 @@ ...@@ -38,8 +38,8 @@
#define DEB(x) if (i2c_debug>=1) x; #define DEB(x) if (i2c_debug>=1) x;
#define DEB2(x) if (i2c_debug>=2) x; #define DEB2(x) if (i2c_debug>=2) x;
static struct i2c_adapter *adapters[I2C_ADAP_MAX]; static LIST_HEAD(adapters);
static struct i2c_driver *drivers[I2C_DRIVER_MAX]; static LIST_HEAD(drivers);
static DECLARE_MUTEX(core_lists); static DECLARE_MUTEX(core_lists);
/**** debug level */ /**** debug level */
...@@ -75,23 +75,17 @@ static struct device_driver i2c_generic_driver = { ...@@ -75,23 +75,17 @@ static struct device_driver i2c_generic_driver = {
*/ */
int i2c_add_adapter(struct i2c_adapter *adap) int i2c_add_adapter(struct i2c_adapter *adap)
{ {
int res = 0, i, j; static int nr = 0;
struct list_head *item;
struct i2c_driver *driver;
down(&core_lists); down(&core_lists);
for (i = 0; i < I2C_ADAP_MAX; i++)
if (NULL == adapters[i])
break;
if (I2C_ADAP_MAX == i) {
dev_warn(&adap->dev,
"register_adapter - enlarge I2C_ADAP_MAX.\n");
res = -ENOMEM;
goto out_unlock;
}
adapters[i] = adap; adap->nr = nr++;
init_MUTEX(&adap->bus_lock);
init_MUTEX(&adap->bus); init_MUTEX(&adap->clist_lock);
init_MUTEX(&adap->list); list_add_tail(&adap->list,&adapters);
INIT_LIST_HEAD(&adap->clients);
/* Add the adapter to the driver core. /* Add the adapter to the driver core.
* If the parent pointer is not set up, * If the parent pointer is not set up,
...@@ -99,59 +93,49 @@ int i2c_add_adapter(struct i2c_adapter *adap) ...@@ -99,59 +93,49 @@ int i2c_add_adapter(struct i2c_adapter *adap)
*/ */
if (adap->dev.parent == NULL) if (adap->dev.parent == NULL)
adap->dev.parent = &legacy_bus; adap->dev.parent = &legacy_bus;
sprintf(adap->dev.bus_id, "i2c-%d", i); sprintf(adap->dev.bus_id, "i2c-%d", adap->nr);
adap->dev.driver = &i2c_generic_driver; adap->dev.driver = &i2c_generic_driver;
device_register(&adap->dev); device_register(&adap->dev);
/* inform drivers of new adapters */ /* inform drivers of new adapters */
for (j=0;j<I2C_DRIVER_MAX;j++) list_for_each(item,&drivers) {
if (drivers[j]!=NULL && driver = list_entry(item, struct i2c_driver, list);
(drivers[j]->flags&(I2C_DF_NOTIFY|I2C_DF_DUMMY))) if (driver->flags & I2C_DF_NOTIFY)
/* We ignore the return code; if it fails, too bad */ /* We ignore the return code; if it fails, too bad */
drivers[j]->attach_adapter(adap); driver->attach_adapter(adap);
}
up(&core_lists); up(&core_lists);
DEB(dev_dbg(&adap->dev, "registered as adapter %d.\n", i)); DEB(dev_dbg(&adap->dev, "registered as adapter #%d\n", adap->nr));
return 0;
out_unlock:
up(&core_lists);
return res;;
} }
int i2c_del_adapter(struct i2c_adapter *adap) int i2c_del_adapter(struct i2c_adapter *adap)
{ {
int res = 0, i, j; struct list_head *item;
struct i2c_driver *driver;
struct i2c_client *client;
int res = 0;
down(&core_lists); down(&core_lists);
for (i = 0; i < I2C_ADAP_MAX; i++)
if (adap == adapters[i])
break;
if (I2C_ADAP_MAX == i) {
dev_warn(&adap->dev, "unregister_adapter adap not found.\n");
res = -ENODEV;
goto out_unlock;
}
/* DUMMY drivers do not register their clients, so we have to list_for_each(item,&drivers) {
* use a trick here: we call driver->attach_adapter to driver = list_entry(item, struct i2c_driver, list);
* *detach* it! Of course, each dummy driver should know about if (driver->detach_adapter)
* this or hell will break loose... if ((res = driver->detach_adapter(adap))) {
*/
for (j = 0; j < I2C_DRIVER_MAX; j++)
if (drivers[j] && (drivers[j]->flags & I2C_DF_DUMMY))
if ((res = drivers[j]->attach_adapter(adap))) {
dev_warn(&adap->dev, "can't detach adapter" dev_warn(&adap->dev, "can't detach adapter"
"while detaching driver %s: driver not " "while detaching driver %s: driver not "
"detached!", drivers[j]->name); "detached!", driver->name);
goto out_unlock; goto out_unlock;
} }
}
/* detach any active clients. This must be done first, because /* detach any active clients. This must be done first, because
* it can fail; in which case we give upp. */ * it can fail; in which case we give upp. */
for (j=0;j<I2C_CLIENT_MAX;j++) { list_for_each(item,&adap->clients) {
struct i2c_client *client = adap->clients[j]; client = list_entry(item, struct i2c_client, list);
if (client!=NULL) {
/* detaching devices is unconditional of the set notify /* detaching devices is unconditional of the set notify
* flag, as _all_ clients that reside on the adapter * flag, as _all_ clients that reside on the adapter
* must be deleted, as this would cause invalid states. * must be deleted, as this would cause invalid states.
...@@ -164,12 +148,10 @@ int i2c_del_adapter(struct i2c_adapter *adap) ...@@ -164,12 +148,10 @@ int i2c_del_adapter(struct i2c_adapter *adap)
goto out_unlock; goto out_unlock;
} }
} }
}
/* clean up the sysfs representation */ /* clean up the sysfs representation */
device_unregister(&adap->dev); device_unregister(&adap->dev);
list_del(&adap->list);
adapters[i] = NULL;
DEB(dev_dbg(&adap->dev, "adapter unregistered\n")); DEB(dev_dbg(&adap->dev, "adapter unregistered\n"));
...@@ -187,24 +169,11 @@ int i2c_del_adapter(struct i2c_adapter *adap) ...@@ -187,24 +169,11 @@ int i2c_del_adapter(struct i2c_adapter *adap)
int i2c_add_driver(struct i2c_driver *driver) int i2c_add_driver(struct i2c_driver *driver)
{ {
int res = 0, i; struct list_head *item;
struct i2c_adapter *adapter;
int res = 0;
down(&core_lists); down(&core_lists);
for (i = 0; i < I2C_DRIVER_MAX; i++)
if (NULL == drivers[i])
break;
if (I2C_DRIVER_MAX == i) {
printk(KERN_WARNING
" i2c-core.o: register_driver(%s) "
"- enlarge I2C_DRIVER_MAX.\n",
driver->name);
res = -ENOMEM;
goto out_unlock;
}
drivers[i] = driver;
DEB(printk(KERN_DEBUG "i2c-core.o: driver %s registered.\n",driver->name));
/* add the driver to the list of i2c drivers in the driver core */ /* add the driver to the list of i2c drivers in the driver core */
driver->driver.name = driver->name; driver->driver.name = driver->name;
...@@ -216,13 +185,14 @@ int i2c_add_driver(struct i2c_driver *driver) ...@@ -216,13 +185,14 @@ int i2c_add_driver(struct i2c_driver *driver)
if (res) if (res)
goto out_unlock; goto out_unlock;
/* now look for instances of driver on our adapters list_add_tail(&driver->list,&drivers);
*/ DEB(printk(KERN_DEBUG "i2c-core.o: driver %s registered.\n",driver->name));
if (driver->flags& (I2C_DF_NOTIFY|I2C_DF_DUMMY)) {
for (i=0;i<I2C_ADAP_MAX;i++) { /* now look for instances of driver on our adapters */
if (adapters[i]!=NULL) if (driver->flags & I2C_DF_NOTIFY) {
/* Ignore errors */ list_for_each(item,&adapters) {
driver->attach_adapter(adapters[i]); adapter = list_entry(item, struct i2c_adapter, list);
driver->attach_adapter(adapter);
} }
} }
...@@ -233,44 +203,29 @@ int i2c_add_driver(struct i2c_driver *driver) ...@@ -233,44 +203,29 @@ int i2c_add_driver(struct i2c_driver *driver)
int i2c_del_driver(struct i2c_driver *driver) int i2c_del_driver(struct i2c_driver *driver)
{ {
int res = 0, i, j, k; struct list_head *item1;
struct list_head *item2;
struct i2c_client *client;
struct i2c_adapter *adap;
down(&core_lists); int res = 0;
for (i = 0; i < I2C_DRIVER_MAX; i++)
if (driver == drivers[i])
break;
if (I2C_DRIVER_MAX == i) {
printk(KERN_WARNING " i2c-core.o: unregister_driver: "
"[%s] not found\n",
driver->name);
res = -ENODEV;
goto out_unlock;
}
driver_unregister(&driver->driver); down(&core_lists);
/* Have a look at each adapter, if clients of this driver are still /* Have a look at each adapter, if clients of this driver are still
* attached. If so, detach them to be able to kill the driver * attached. If so, detach them to be able to kill the driver
* afterwards. * afterwards.
*/ */
DEB2(printk(KERN_DEBUG "i2c-core.o: unregister_driver - looking for clients.\n")); DEB2(printk(KERN_DEBUG "i2c-core.o: unregister_driver - looking for clients.\n"));
/* removing clients does not depend on the notify flag, else /* removing clients does not depend on the notify flag, else
* invalid operation might (will!) result, when using stale client * invalid operation might (will!) result, when using stale client
* pointers. * pointers.
*/ */
for (k=0;k<I2C_ADAP_MAX;k++) { list_for_each(item1,&adapters) {
struct i2c_adapter *adap = adapters[k]; adap = list_entry(item1, struct i2c_adapter, list);
if (adap == NULL) /* skip empty entries. */
continue;
DEB2(dev_dbg(&adap->dev, "examining adapter\n")); DEB2(dev_dbg(&adap->dev, "examining adapter\n"));
if (driver->flags & I2C_DF_DUMMY) { if (driver->detach_adapter) {
/* DUMMY drivers do not register their clients, so we have to if ((res = driver->detach_adapter(adap))) {
* use a trick here: we call driver->attach_adapter to
* *detach* it! Of course, each dummy driver should know about
* this or hell will break loose...
*/
if ((res = driver->attach_adapter(adap))) {
dev_warn(&adap->dev, "while unregistering " dev_warn(&adap->dev, "while unregistering "
"dummy driver %s, adapter could " "dummy driver %s, adapter could "
"not be detached properly; driver " "not be detached properly; driver "
...@@ -278,10 +233,10 @@ int i2c_del_driver(struct i2c_driver *driver) ...@@ -278,10 +233,10 @@ int i2c_del_driver(struct i2c_driver *driver)
goto out_unlock; goto out_unlock;
} }
} else { } else {
for (j=0;j<I2C_CLIENT_MAX;j++) { list_for_each(item2,&adap->clients) {
struct i2c_client *client = adap->clients[j]; client = list_entry(item2, struct i2c_client, list);
if (client != NULL && if (client->driver != driver)
client->driver == driver) { continue;
DEB2(printk(KERN_DEBUG "i2c-core.o: " DEB2(printk(KERN_DEBUG "i2c-core.o: "
"detaching client %s:\n", "detaching client %s:\n",
client->dev.name)); client->dev.name));
...@@ -300,9 +255,9 @@ int i2c_del_driver(struct i2c_driver *driver) ...@@ -300,9 +255,9 @@ int i2c_del_driver(struct i2c_driver *driver)
} }
} }
} }
}
drivers[i] = NULL;
driver_unregister(&driver->driver);
list_del(&driver->list);
DEB(printk(KERN_DEBUG "i2c-core.o: driver unregistered: %s\n",driver->name)); DEB(printk(KERN_DEBUG "i2c-core.o: driver unregistered: %s\n",driver->name));
out_unlock: out_unlock:
...@@ -310,14 +265,16 @@ int i2c_del_driver(struct i2c_driver *driver) ...@@ -310,14 +265,16 @@ int i2c_del_driver(struct i2c_driver *driver)
return 0; return 0;
} }
static int __i2c_check_addr(struct i2c_adapter *adapter, int addr) static int __i2c_check_addr(struct i2c_adapter *adapter, unsigned int addr)
{ {
int i; struct list_head *item;
struct i2c_client *client;
for (i = 0; i < I2C_CLIENT_MAX ; i++) list_for_each(item,&adapter->clients) {
if (adapter->clients[i] && (adapter->clients[i]->addr == addr)) client = list_entry(item, struct i2c_client, list);
if (client->addr == addr)
return -EBUSY; return -EBUSY;
}
return 0; return 0;
} }
...@@ -325,9 +282,9 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr) ...@@ -325,9 +282,9 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr)
{ {
int rval; int rval;
down(&adapter->list); down(&adapter->clist_lock);
rval = __i2c_check_addr(adapter, addr); rval = __i2c_check_addr(adapter, addr);
up(&adapter->list); up(&adapter->clist_lock);
return rval; return rval;
} }
...@@ -335,28 +292,14 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr) ...@@ -335,28 +292,14 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr)
int i2c_attach_client(struct i2c_client *client) int i2c_attach_client(struct i2c_client *client)
{ {
struct i2c_adapter *adapter = client->adapter; struct i2c_adapter *adapter = client->adapter;
int i;
down(&adapter->list);
if (__i2c_check_addr(client->adapter, client->addr))
goto out_unlock_list;
for (i = 0; i < I2C_CLIENT_MAX; i++) {
if (!adapter->clients[i])
goto free_slot;
}
printk(KERN_WARNING down(&adapter->clist_lock);
" i2c-core.o: attach_client(%s) - enlarge I2C_CLIENT_MAX.\n", if (__i2c_check_addr(client->adapter, client->addr)) {
client->dev.name); up(&adapter->clist_lock);
out_unlock_list:
up(&adapter->list);
return -EBUSY; return -EBUSY;
}
free_slot: list_add_tail(&client->list,&adapter->clients);
adapter->clients[i] = client; up(&adapter->clist_lock);
up(&adapter->list);
if (adapter->client_register) { if (adapter->client_register) {
if (adapter->client_register(client)) { if (adapter->client_register(client)) {
...@@ -366,8 +309,8 @@ int i2c_attach_client(struct i2c_client *client) ...@@ -366,8 +309,8 @@ int i2c_attach_client(struct i2c_client *client)
} }
} }
DEB(dev_dbg(&adapter->dev, "client [%s] registered to adapter " DEB(dev_dbg(&adapter->dev, "client [%s] registered to adapter\n",
"(pos. %d).\n", client->dev.name, i)); client->dev.name));
if (client->flags & I2C_CLIENT_ALLOW_USE) if (client->flags & I2C_CLIENT_ALLOW_USE)
client->usage_count = 0; client->usage_count = 0;
...@@ -388,7 +331,7 @@ int i2c_attach_client(struct i2c_client *client) ...@@ -388,7 +331,7 @@ int i2c_attach_client(struct i2c_client *client)
int i2c_detach_client(struct i2c_client *client) int i2c_detach_client(struct i2c_client *client)
{ {
struct i2c_adapter *adapter = client->adapter; struct i2c_adapter *adapter = client->adapter;
int res = 0, i; int res = 0;
if ((client->flags & I2C_CLIENT_ALLOW_USE) && (client->usage_count > 0)) if ((client->flags & I2C_CLIENT_ALLOW_USE) && (client->usage_count > 0))
return -EBUSY; return -EBUSY;
...@@ -403,22 +346,11 @@ int i2c_detach_client(struct i2c_client *client) ...@@ -403,22 +346,11 @@ int i2c_detach_client(struct i2c_client *client)
} }
} }
down(&adapter->list); down(&adapter->clist_lock);
for (i = 0; i < I2C_CLIENT_MAX; i++) { list_del(&client->list);
if (client == adapter->clients[i]) {
adapter->clients[i] = NULL;
goto out_unlock;
}
}
printk(KERN_WARNING
" i2c-core.o: unregister_client [%s] not found\n",
client->dev.name);
res = -ENODEV;
out_unlock:
device_unregister(&client->dev); device_unregister(&client->dev);
up(&adapter->list); up(&adapter->clist_lock);
out: out:
return res; return res;
} }
...@@ -479,6 +411,27 @@ int i2c_release_client(struct i2c_client *client) ...@@ -479,6 +411,27 @@ int i2c_release_client(struct i2c_client *client)
return 0; return 0;
} }
void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg)
{
struct list_head *item;
struct i2c_client *client;
down(&adap->clist_lock);
list_for_each(item,&adap->clients) {
client = list_entry(item, struct i2c_client, list);
if (!try_module_get(client->driver->owner))
continue;
if (NULL != client->driver->command) {
up(&adap->clist_lock);
client->driver->command(client,cmd,arg);
down(&adap->clist_lock);
}
module_put(client->driver->owner);
}
up(&adap->clist_lock);
}
/* match always succeeds, as we want the probe() to tell if we really accept this match */ /* match always succeeds, as we want the probe() to tell if we really accept this match */
static int i2c_device_match(struct device *dev, struct device_driver *drv) static int i2c_device_match(struct device *dev, struct device_driver *drv)
{ {
...@@ -516,9 +469,9 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg msgs[],int num) ...@@ -516,9 +469,9 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg msgs[],int num)
if (adap->algo->master_xfer) { if (adap->algo->master_xfer) {
DEB2(dev_dbg(&adap->dev, "master_xfer: with %d msgs.\n", num)); DEB2(dev_dbg(&adap->dev, "master_xfer: with %d msgs.\n", num));
down(&adap->bus); down(&adap->bus_lock);
ret = adap->algo->master_xfer(adap,msgs,num); ret = adap->algo->master_xfer(adap,msgs,num);
up(&adap->bus); up(&adap->bus_lock);
return ret; return ret;
} else { } else {
...@@ -542,9 +495,9 @@ int i2c_master_send(struct i2c_client *client,const char *buf ,int count) ...@@ -542,9 +495,9 @@ int i2c_master_send(struct i2c_client *client,const char *buf ,int count)
DEB2(dev_dbg(&client->adapter->dev, "master_send: writing %d bytes.\n", DEB2(dev_dbg(&client->adapter->dev, "master_send: writing %d bytes.\n",
count)); count));
down(&adap->bus); down(&adap->bus_lock);
ret = adap->algo->master_xfer(adap,&msg,1); ret = adap->algo->master_xfer(adap,&msg,1);
up(&adap->bus); up(&adap->bus_lock);
/* if everything went ok (i.e. 1 msg transmitted), return #bytes /* if everything went ok (i.e. 1 msg transmitted), return #bytes
* transmitted, else error code. * transmitted, else error code.
...@@ -572,9 +525,9 @@ int i2c_master_recv(struct i2c_client *client, char *buf ,int count) ...@@ -572,9 +525,9 @@ int i2c_master_recv(struct i2c_client *client, char *buf ,int count)
DEB2(dev_dbg(&client->adapter->dev, "master_recv: reading %d bytes.\n", DEB2(dev_dbg(&client->adapter->dev, "master_recv: reading %d bytes.\n",
count)); count));
down(&adap->bus); down(&adap->bus_lock);
ret = adap->algo->master_xfer(adap,&msg,1); ret = adap->algo->master_xfer(adap,&msg,1);
up(&adap->bus); up(&adap->bus_lock);
DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: return:%d (count:%d, addr:0x%02x)\n", DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: return:%d (count:%d, addr:0x%02x)\n",
ret, count, client->addr)); ret, count, client->addr));
...@@ -743,11 +696,30 @@ int i2c_probe(struct i2c_adapter *adapter, ...@@ -743,11 +696,30 @@ int i2c_probe(struct i2c_adapter *adapter,
*/ */
int i2c_adapter_id(struct i2c_adapter *adap) int i2c_adapter_id(struct i2c_adapter *adap)
{ {
int i; return adap->nr;
for (i = 0; i < I2C_ADAP_MAX; i++) }
if (adap == adapters[i])
return i; struct i2c_adapter* i2c_get_adapter(int id)
return -1; {
struct list_head *item;
struct i2c_adapter *adapter;
down(&core_lists);
list_for_each(item,&adapters) {
adapter = list_entry(item, struct i2c_adapter, list);
if (id == adapter->nr &&
try_module_get(adapter->owner)) {
up(&core_lists);
return adapter;
}
}
up(&core_lists);
return NULL;
}
void i2c_put_adapter(struct i2c_adapter *adap)
{
module_put(adap->owner);
} }
/* The SMBus parts */ /* The SMBus parts */
...@@ -1189,10 +1161,10 @@ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags, ...@@ -1189,10 +1161,10 @@ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags,
} }
if (adapter->algo->smbus_xfer) { if (adapter->algo->smbus_xfer) {
down(&adapter->bus); down(&adapter->bus_lock);
res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write, res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write,
command,size,data); command,size,data);
up(&adapter->bus); up(&adapter->bus_lock);
} else } else
res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
command,size,data); command,size,data);
...@@ -1232,6 +1204,7 @@ EXPORT_SYMBOL(i2c_attach_client); ...@@ -1232,6 +1204,7 @@ EXPORT_SYMBOL(i2c_attach_client);
EXPORT_SYMBOL(i2c_detach_client); EXPORT_SYMBOL(i2c_detach_client);
EXPORT_SYMBOL(i2c_use_client); EXPORT_SYMBOL(i2c_use_client);
EXPORT_SYMBOL(i2c_release_client); EXPORT_SYMBOL(i2c_release_client);
EXPORT_SYMBOL(i2c_clients_command);
EXPORT_SYMBOL(i2c_check_addr); EXPORT_SYMBOL(i2c_check_addr);
EXPORT_SYMBOL(i2c_master_send); EXPORT_SYMBOL(i2c_master_send);
...@@ -1239,6 +1212,8 @@ EXPORT_SYMBOL(i2c_master_recv); ...@@ -1239,6 +1212,8 @@ EXPORT_SYMBOL(i2c_master_recv);
EXPORT_SYMBOL(i2c_control); EXPORT_SYMBOL(i2c_control);
EXPORT_SYMBOL(i2c_transfer); EXPORT_SYMBOL(i2c_transfer);
EXPORT_SYMBOL(i2c_adapter_id); EXPORT_SYMBOL(i2c_adapter_id);
EXPORT_SYMBOL(i2c_get_adapter);
EXPORT_SYMBOL(i2c_put_adapter);
EXPORT_SYMBOL(i2c_probe); EXPORT_SYMBOL(i2c_probe);
EXPORT_SYMBOL(i2c_smbus_xfer); EXPORT_SYMBOL(i2c_smbus_xfer);
......
...@@ -58,6 +58,7 @@ static int i2cdev_open (struct inode *inode, struct file *file); ...@@ -58,6 +58,7 @@ static int i2cdev_open (struct inode *inode, struct file *file);
static int i2cdev_release (struct inode *inode, struct file *file); static int i2cdev_release (struct inode *inode, struct file *file);
static int i2cdev_attach_adapter(struct i2c_adapter *adap); static int i2cdev_attach_adapter(struct i2c_adapter *adap);
static int i2cdev_detach_adapter(struct i2c_adapter *adap);
static int i2cdev_detach_client(struct i2c_client *client); static int i2cdev_detach_client(struct i2c_client *client);
static int i2cdev_command(struct i2c_client *client, unsigned int cmd, static int i2cdev_command(struct i2c_client *client, unsigned int cmd,
void *arg); void *arg);
...@@ -72,15 +73,13 @@ static struct file_operations i2cdev_fops = { ...@@ -72,15 +73,13 @@ static struct file_operations i2cdev_fops = {
.release = i2cdev_release, .release = i2cdev_release,
}; };
#define I2CDEV_ADAPS_MAX I2C_ADAP_MAX
static struct i2c_adapter *i2cdev_adaps[I2CDEV_ADAPS_MAX];
static struct i2c_driver i2cdev_driver = { static struct i2c_driver i2cdev_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "dev driver", .name = "dev driver",
.id = I2C_DRIVERID_I2CDEV, .id = I2C_DRIVERID_I2CDEV,
.flags = I2C_DF_DUMMY, .flags = I2C_DF_NOTIFY,
.attach_adapter = i2cdev_attach_adapter, .attach_adapter = i2cdev_attach_adapter,
.detach_adapter = i2cdev_detach_adapter,
.detach_client = i2cdev_detach_client, .detach_client = i2cdev_detach_client,
.command = i2cdev_command, .command = i2cdev_command,
}; };
...@@ -340,35 +339,31 @@ static int i2cdev_open(struct inode *inode, struct file *file) ...@@ -340,35 +339,31 @@ static int i2cdev_open(struct inode *inode, struct file *file)
{ {
unsigned int minor = minor(inode->i_rdev); unsigned int minor = minor(inode->i_rdev);
struct i2c_client *client; struct i2c_client *client;
struct i2c_adapter *adap;
if ((minor >= I2CDEV_ADAPS_MAX) || !(i2cdev_adaps[minor])) adap = i2c_get_adapter(minor);
if (NULL == adap)
return -ENODEV; return -ENODEV;
client = kmalloc(sizeof(*client), GFP_KERNEL); client = kmalloc(sizeof(*client), GFP_KERNEL);
if (!client) if (!client) {
i2c_put_adapter(adap);
return -ENOMEM; return -ENOMEM;
}
memcpy(client, &i2cdev_client_template, sizeof(*client)); memcpy(client, &i2cdev_client_template, sizeof(*client));
/* registered with adapter, passed as client to user */ /* registered with adapter, passed as client to user */
client->adapter = i2cdev_adaps[minor]; client->adapter = adap;
file->private_data = client; file->private_data = client;
/* use adapter module, i2c-dev handled with fops */
if (!try_module_get(client->adapter->owner))
goto out_kfree;
return 0; return 0;
out_kfree:
kfree(client);
return -ENODEV;
} }
static int i2cdev_release(struct inode *inode, struct file *file) static int i2cdev_release(struct inode *inode, struct file *file)
{ {
struct i2c_client *client = file->private_data; struct i2c_client *client = file->private_data;
module_put(client->adapter->owner); i2c_put_adapter(client->adapter);
kfree(client); kfree(client);
file->private_data = NULL; file->private_data = NULL;
...@@ -377,33 +372,28 @@ static int i2cdev_release(struct inode *inode, struct file *file) ...@@ -377,33 +372,28 @@ static int i2cdev_release(struct inode *inode, struct file *file)
int i2cdev_attach_adapter(struct i2c_adapter *adap) int i2cdev_attach_adapter(struct i2c_adapter *adap)
{ {
int i;
char name[12]; char name[12];
int i;
if ((i = i2c_adapter_id(adap)) < 0) { i = i2c_adapter_id(adap);
dev_dbg(&adap->dev, "Unknown adapter ?!?\n");
return -ENODEV;
}
if (i >= I2CDEV_ADAPS_MAX) {
dev_dbg(&adap->dev, "Adapter number too large?!? (%d)\n",i);
return -ENODEV;
}
sprintf (name, "i2c/%d", i); sprintf (name, "i2c/%d", i);
if (! i2cdev_adaps[i]) {
i2cdev_adaps[i] = adap;
devfs_register (NULL, name, devfs_register (NULL, name,
DEVFS_FL_DEFAULT, I2C_MAJOR, i, DEVFS_FL_DEFAULT, I2C_MAJOR, i,
S_IFCHR | S_IRUSR | S_IWUSR, S_IFCHR | S_IRUSR | S_IWUSR,
&i2cdev_fops, NULL); &i2cdev_fops, NULL);
dev_dbg(&adap->dev, "Registered as minor %d\n", i); dev_dbg(&adap->dev, "Registered as minor %d\n", i);
} else { return 0;
/* This is actually a detach_adapter call! */ }
int i2cdev_detach_adapter(struct i2c_adapter *adap)
{
int i;
i = i2c_adapter_id(adap);
devfs_remove("i2c/%d", i); devfs_remove("i2c/%d", i);
i2cdev_adaps[i] = NULL;
dev_dbg(&adap->dev, "Adapter unregistered\n"); dev_dbg(&adap->dev, "Adapter unregistered\n");
}
return 0; return 0;
} }
......
...@@ -212,7 +212,7 @@ handle_interrupt(struct keywest_iface *iface, u8 isr) ...@@ -212,7 +212,7 @@ handle_interrupt(struct keywest_iface *iface, u8 isr)
#ifndef POLLED_MODE #ifndef POLLED_MODE
/* Interrupt handler */ /* Interrupt handler */
static void static irqreturn_t
keywest_irq(int irq, void *dev_id, struct pt_regs *regs) keywest_irq(int irq, void *dev_id, struct pt_regs *regs)
{ {
struct keywest_iface *iface = (struct keywest_iface *)dev_id; struct keywest_iface *iface = (struct keywest_iface *)dev_id;
...@@ -225,6 +225,7 @@ keywest_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -225,6 +225,7 @@ keywest_irq(int irq, void *dev_id, struct pt_regs *regs)
add_timer(&iface->timeout_timer); add_timer(&iface->timeout_timer);
} }
spin_unlock(&iface->lock); spin_unlock(&iface->lock);
return IRQ_HANDLED;
} }
static void static void
......
...@@ -198,25 +198,9 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, ...@@ -198,25 +198,9 @@ static int bt832_attach(struct i2c_adapter *adap, int addr,
static int bt832_probe(struct i2c_adapter *adap) static int bt832_probe(struct i2c_adapter *adap)
{ {
int rc; if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
return i2c_probe(adap, &addr_data, bt832_attach);
printk("bt832_probe\n"); return 0;
switch (adap->id) {
case I2C_ALGO_BIT | I2C_HW_B_BT848:
case I2C_ALGO_BIT | I2C_HW_B_RIVA:
case I2C_ALGO_SAA7134:
printk("bt832: probing %s i2c adapter [id=0x%x]\n",
adap->name,adap->id);
rc = i2c_probe(adap, &addr_data, bt832_attach);
break;
default:
printk("bt832: ignoring %s i2c adapter [id=0x%x]\n",
adap->name,adap->id);
rc = 0;
/* nothing */
}
return rc;
} }
static int bt832_detach(struct i2c_client *client) static int bt832_detach(struct i2c_client *client)
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
& Marcus Metzler (mocm@thp.uni-koeln.de) & Marcus Metzler (mocm@thp.uni-koeln.de)
(c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de> (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -195,51 +195,21 @@ static int bttv_bit_getsda(void *data) ...@@ -195,51 +195,21 @@ static int bttv_bit_getsda(void *data)
static int attach_inform(struct i2c_client *client) static int attach_inform(struct i2c_client *client)
{ {
struct bttv *btv = i2c_get_adapdata(client->adapter); struct bttv *btv = i2c_get_adapdata(client->adapter);
int i;
for (i = 0; i < I2C_CLIENTS_MAX; i++) { if (btv->tuner_type != UNSET)
if (btv->i2c_clients[i] == NULL) {
btv->i2c_clients[i] = client;
break;
}
}
if (btv->tuner_type != -1)
bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type); bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
if (bttv_verbose)
printk("bttv%d: i2c attach [client=%s,%s]\n",btv->nr,
client->dev.name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed");
return 0;
}
static int detach_inform(struct i2c_client *client)
{
struct bttv *btv = i2c_get_adapdata(client->adapter);
int i;
for (i = 0; i < I2C_CLIENTS_MAX; i++) { if (bttv_debug)
if (btv->i2c_clients[i] == client) { printk("bttv%d: i2c attach [client=%s]\n",
btv->i2c_clients[i] = NULL; btv->nr, i2c_clientname(client));
break;
}
}
if (bttv_verbose)
printk("bttv%d: i2c detach [client=%s,%s]\n",btv->nr,
client->dev.name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed");
return 0; return 0;
} }
void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg) void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
{ {
int i; if (0 != btv->i2c_rc)
return;
for (i = 0; i < I2C_CLIENTS_MAX; i++) { i2c_clients_command(&btv->i2c_adap, cmd, arg);
if (NULL == btv->i2c_clients[i])
continue;
if (NULL == btv->i2c_clients[i]->driver->command)
continue;
btv->i2c_clients[i]->driver->command(
btv->i2c_clients[i],cmd,arg);
}
} }
void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg) void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg)
...@@ -261,19 +231,15 @@ static struct i2c_algo_bit_data bttv_i2c_algo_template = { ...@@ -261,19 +231,15 @@ static struct i2c_algo_bit_data bttv_i2c_algo_template = {
static struct i2c_adapter bttv_i2c_adap_template = { static struct i2c_adapter bttv_i2c_adap_template = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
I2C_DEVNAME("bt848"),
.id = I2C_HW_B_BT848, .id = I2C_HW_B_BT848,
.class = I2C_ADAP_CLASS_TV_ANALOG,
.client_register = attach_inform, .client_register = attach_inform,
.client_unregister = detach_inform,
.dev = {
.name = "bt848",
},
}; };
static struct i2c_client bttv_i2c_client_template = { static struct i2c_client bttv_i2c_client_template = {
I2C_DEVNAME("bttv internal"),
.id = -1, .id = -1,
.dev = {
.name = "bttv internal",
},
}; };
...@@ -347,8 +313,8 @@ int __devinit init_bttv_i2c(struct bttv *btv) ...@@ -347,8 +313,8 @@ int __devinit init_bttv_i2c(struct bttv *btv)
memcpy(&btv->i2c_client, &bttv_i2c_client_template, memcpy(&btv->i2c_client, &bttv_i2c_client_template,
sizeof(struct i2c_client)); sizeof(struct i2c_client));
sprintf(btv->i2c_adap.dev.name+strlen(btv->i2c_adap.dev.name), sprintf(btv->i2c_adap.dev.name, "bt848 #%d", btv->nr);
" #%d", btv->nr);
btv->i2c_algo.data = btv; btv->i2c_algo.data = btv;
i2c_set_adapdata(&btv->i2c_adap, btv); i2c_set_adapdata(&btv->i2c_adap, btv);
btv->i2c_adap.algo_data = &btv->i2c_algo; btv->i2c_adap.algo_data = &btv->i2c_algo;
......
...@@ -243,7 +243,6 @@ extern void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg); ...@@ -243,7 +243,6 @@ extern void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg);
/* i2c */ /* i2c */
#define I2C_CLIENTS_MAX 16
extern void bttv_bit_setscl(void *data, int state); extern void bttv_bit_setscl(void *data, int state);
extern void bttv_bit_setsda(void *data, int state); extern void bttv_bit_setsda(void *data, int state);
extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg); extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg);
......
...@@ -62,6 +62,8 @@ ...@@ -62,6 +62,8 @@
#define RAW_LINES 640 #define RAW_LINES 640
#define RAW_BPL 1024 #define RAW_BPL 1024
#define UNSET (-1U)
/* ---------------------------------------------------------- */ /* ---------------------------------------------------------- */
struct bttv_tvnorm struct bttv_tvnorm
...@@ -276,7 +278,6 @@ struct bttv { ...@@ -276,7 +278,6 @@ struct bttv {
struct i2c_algo_bit_data i2c_algo; struct i2c_algo_bit_data i2c_algo;
struct i2c_client i2c_client; struct i2c_client i2c_client;
int i2c_state, i2c_rc; int i2c_state, i2c_rc;
struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];
/* video4linux (1) */ /* video4linux (1) */
struct video_device video_dev; struct video_device video_dev;
......
...@@ -96,7 +96,8 @@ struct dpc ...@@ -96,7 +96,8 @@ struct dpc
static int dpc_probe(struct saa7146_dev* dev) static int dpc_probe(struct saa7146_dev* dev)
{ {
struct dpc* dpc = 0; struct dpc* dpc = 0;
int i = 0; struct i2c_client *client;
struct list_head *item;
dpc = (struct dpc*)kmalloc(sizeof(struct dpc), GFP_KERNEL); dpc = (struct dpc*)kmalloc(sizeof(struct dpc), GFP_KERNEL);
if( NULL == dpc ) { if( NULL == dpc ) {
...@@ -117,12 +118,10 @@ static int dpc_probe(struct saa7146_dev* dev) ...@@ -117,12 +118,10 @@ static int dpc_probe(struct saa7146_dev* dev)
} }
/* loop through all i2c-devices on the bus and look who is there */ /* loop through all i2c-devices on the bus and look who is there */
for(i = 0; i < I2C_CLIENT_MAX; i++) { list_for_each(item,&dpc->i2c_adapter.clients) {
if( NULL == dpc->i2c_adapter.clients[i] ) { client = list_entry(item, struct i2c_client, list);
continue; if( I2C_SAA7111A == client->addr )
} dpc->saa7111a = client;
if( I2C_SAA7111A == dpc->i2c_adapter.clients[i]->addr )
dpc->saa7111a = dpc->i2c_adapter.clients[i];
} }
/* check if all devices are present */ /* check if all devices are present */
......
...@@ -1372,7 +1372,7 @@ static int msp_detach(struct i2c_client *client) ...@@ -1372,7 +1372,7 @@ static int msp_detach(struct i2c_client *client)
static int msp_probe(struct i2c_adapter *adap) static int msp_probe(struct i2c_adapter *adap)
{ {
if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
return i2c_probe(adap, &addr_data, msp_attach); return i2c_probe(adap, &addr_data, msp_attach);
return 0; return 0;
} }
......
...@@ -208,7 +208,8 @@ static int mxb_vbi_bypass(struct saa7146_dev* dev) ...@@ -208,7 +208,8 @@ static int mxb_vbi_bypass(struct saa7146_dev* dev)
static int mxb_probe(struct saa7146_dev* dev) static int mxb_probe(struct saa7146_dev* dev)
{ {
struct mxb* mxb = 0; struct mxb* mxb = 0;
int i = 0; struct i2c_client *client;
struct list_head *item;
request_module("tuner"); request_module("tuner");
request_module("tea6420"); request_module("tea6420");
...@@ -235,22 +236,20 @@ static int mxb_probe(struct saa7146_dev* dev) ...@@ -235,22 +236,20 @@ static int mxb_probe(struct saa7146_dev* dev)
} }
/* loop through all i2c-devices on the bus and look who is there */ /* loop through all i2c-devices on the bus and look who is there */
for(i = 0; i < I2C_CLIENT_MAX; i++) { list_for_each(item,&mxb->i2c_adapter.clients) {
if( NULL == mxb->i2c_adapter.clients[i] ) { client = list_entry(item, struct i2c_client, list);
continue; if( I2C_TEA6420_1 == client->addr )
} mxb->tea6420_1 = client;
if( I2C_TEA6420_1 == mxb->i2c_adapter.clients[i]->addr ) if( I2C_TEA6420_2 == client->addr )
mxb->tea6420_1 = mxb->i2c_adapter.clients[i]; mxb->tea6420_2 = client;
if( I2C_TEA6420_2 == mxb->i2c_adapter.clients[i]->addr ) if( I2C_TEA6415C_2 == client->addr )
mxb->tea6420_2 = mxb->i2c_adapter.clients[i]; mxb->tea6415c = client;
if( I2C_TEA6415C_2 == mxb->i2c_adapter.clients[i]->addr ) if( I2C_TDA9840 == client->addr )
mxb->tea6415c = mxb->i2c_adapter.clients[i]; mxb->tda9840 = client;
if( I2C_TDA9840 == mxb->i2c_adapter.clients[i]->addr ) if( I2C_SAA7111A == client->addr )
mxb->tda9840 = mxb->i2c_adapter.clients[i]; mxb->saa7111a = client;
if( I2C_SAA7111A == mxb->i2c_adapter.clients[i]->addr ) if( 0x60 == client->addr )
mxb->saa7111a = mxb->i2c_adapter.clients[i]; mxb->tuner = client;
if( 0x60 == mxb->i2c_adapter.clients[i]->addr )
mxb->tuner = mxb->i2c_adapter.clients[i];
} }
/* check if all devices are present */ /* check if all devices are present */
......
...@@ -224,12 +224,8 @@ static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -224,12 +224,8 @@ static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind)
static int saa5249_probe(struct i2c_adapter *adap) static int saa5249_probe(struct i2c_adapter *adap)
{ {
/* Only attach these chips to the BT848 bus for now */ if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
{
return i2c_probe(adap, &addr_data, saa5249_attach); return i2c_probe(adap, &addr_data, saa5249_attach);
}
return 0; return 0;
} }
......
...@@ -334,19 +334,16 @@ static struct i2c_algorithm saa7134_algo = { ...@@ -334,19 +334,16 @@ static struct i2c_algorithm saa7134_algo = {
static struct i2c_adapter saa7134_adap_template = { static struct i2c_adapter saa7134_adap_template = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
I2C_DEVNAME("saa7134"),
.id = I2C_ALGO_SAA7134, .id = I2C_ALGO_SAA7134,
.class = I2C_ADAP_CLASS_TV_ANALOG,
.algo = &saa7134_algo, .algo = &saa7134_algo,
.client_register = attach_inform, .client_register = attach_inform,
.dev = {
.name = "saa7134",
},
}; };
static struct i2c_client saa7134_client_template = { static struct i2c_client saa7134_client_template = {
I2C_DEVNAME("saa7134 internal"),
.id = -1, .id = -1,
.dev = {
.name = "saa7134 internal",
},
}; };
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
...@@ -399,22 +396,13 @@ saa7134_i2c_scan(struct saa7134_dev *dev) ...@@ -399,22 +396,13 @@ saa7134_i2c_scan(struct saa7134_dev *dev)
void saa7134_i2c_call_clients(struct saa7134_dev *dev, void saa7134_i2c_call_clients(struct saa7134_dev *dev,
unsigned int cmd, void *arg) unsigned int cmd, void *arg)
{ {
int i; i2c_clients_command(&dev->i2c_adap, cmd, arg);
for (i = 0; i < I2C_CLIENT_MAX; i++) {
if (NULL == dev->i2c_adap.clients[i])
continue;
if (NULL == dev->i2c_adap.clients[i]->driver->command)
continue;
dev->i2c_adap.clients[i]->driver->command
(dev->i2c_adap.clients[i],cmd,arg);
}
} }
int saa7134_i2c_register(struct saa7134_dev *dev) int saa7134_i2c_register(struct saa7134_dev *dev)
{ {
dev->i2c_adap = saa7134_adap_template; dev->i2c_adap = saa7134_adap_template;
strncpy(dev->i2c_adap.dev.name, dev->name, DEVICE_NAME_SIZE); strcpy(dev->i2c_adap.dev.name,dev->name);
dev->i2c_adap.algo_data = dev; dev->i2c_adap.algo_data = dev;
i2c_add_adapter(&dev->i2c_adap); i2c_add_adapter(&dev->i2c_adap);
......
...@@ -340,7 +340,7 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -340,7 +340,7 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind)
static int tda7432_probe(struct i2c_adapter *adap) static int tda7432_probe(struct i2c_adapter *adap)
{ {
if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
return i2c_probe(adap, &addr_data, tda7432_attach); return i2c_probe(adap, &addr_data, tda7432_attach);
return 0; return 0;
} }
......
...@@ -273,7 +273,7 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -273,7 +273,7 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind)
static int tda9875_probe(struct i2c_adapter *adap) static int tda9875_probe(struct i2c_adapter *adap)
{ {
if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
return i2c_probe(adap, &addr_data, tda9875_attach); return i2c_probe(adap, &addr_data, tda9875_attach);
return 0; return 0;
} }
......
...@@ -368,23 +368,9 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -368,23 +368,9 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
static int tda9887_probe(struct i2c_adapter *adap) static int tda9887_probe(struct i2c_adapter *adap)
{ {
int rc; if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
return i2c_probe(adap, &addr_data, tda9887_attach);
switch (adap->id) { return 0;
case I2C_ALGO_BIT | I2C_HW_B_BT848:
case I2C_ALGO_BIT | I2C_HW_B_RIVA:
case I2C_ALGO_SAA7134:
printk("tda9887: probing %s i2c adapter [id=0x%x]\n",
adap->dev.name,adap->id);
rc = i2c_probe(adap, &addr_data, tda9887_attach);
break;
default:
printk("tda9887: ignoring %s i2c adapter [id=0x%x]\n",
adap->dev.name,adap->id);
rc = 0;
/* nothing */
}
return rc;
} }
static int tda9887_detach(struct i2c_client *client) static int tda9887_detach(struct i2c_client *client)
......
...@@ -817,29 +817,15 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -817,29 +817,15 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
static int tuner_probe(struct i2c_adapter *adap) static int tuner_probe(struct i2c_adapter *adap)
{ {
int rc;
if (0 != addr) { if (0 != addr) {
normal_i2c_range[0] = addr; normal_i2c_range[0] = addr;
normal_i2c_range[1] = addr; normal_i2c_range[1] = addr;
} }
this_adap = 0; this_adap = 0;
switch (adap->id) {
case I2C_ALGO_BIT | I2C_HW_B_BT848: if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
case I2C_ALGO_BIT | I2C_HW_B_RIVA: return i2c_probe(adap, &addr_data, tuner_attach);
case I2C_ALGO_SAA7134: return 0;
case I2C_ALGO_SAA7146:
printk("tuner: probing %s i2c adapter [id=0x%x]\n",
adap->dev.name,adap->id);
rc = i2c_probe(adap, &addr_data, tuner_attach);
break;
default:
printk("tuner: ignoring %s i2c adapter [id=0x%x]\n",
adap->dev.name,adap->id);
rc = 0;
/* nothing */
}
return rc;
} }
static int tuner_detach(struct i2c_client *client) static int tuner_detach(struct i2c_client *client)
......
...@@ -1408,14 +1408,9 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) ...@@ -1408,14 +1408,9 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
static int chip_probe(struct i2c_adapter *adap) static int chip_probe(struct i2c_adapter *adap)
{ {
switch (adap->id) { if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
case I2C_ALGO_BIT | I2C_HW_B_BT848:
case I2C_ALGO_BIT | I2C_HW_B_RIVA:
return i2c_probe(adap, &addr_data, chip_attach); return i2c_probe(adap, &addr_data, chip_attach);
default:
/* ignore this i2c bus */
return 0; return 0;
}
} }
static int chip_detach(struct i2c_client *client) static int chip_detach(struct i2c_client *client)
......
...@@ -217,8 +217,9 @@ static struct i2c_driver driver = { ...@@ -217,8 +217,9 @@ static struct i2c_driver driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "tv card mixer driver", .name = "tv card mixer driver",
.id = I2C_DRIVERID_TVMIXER, .id = I2C_DRIVERID_TVMIXER,
.flags = I2C_DF_DUMMY, .flags = I2C_DF_NOTIFY,
.attach_adapter = tvmixer_adapters, .attach_adapter = tvmixer_adapters,
.detach_adapter = tvmixer_adapters,
.detach_client = tvmixer_clients, .detach_client = tvmixer_clients,
}; };
...@@ -234,14 +235,15 @@ static struct file_operations tvmixer_fops = { ...@@ -234,14 +235,15 @@ static struct file_operations tvmixer_fops = {
static int tvmixer_adapters(struct i2c_adapter *adap) static int tvmixer_adapters(struct i2c_adapter *adap)
{ {
int i; struct list_head *item;
struct i2c_client *client;
if (debug) if (debug)
printk("tvmixer: adapter %s\n",adap->dev.name); printk("tvmixer: adapter %s\n",adap->dev.name);
for (i=0; i<I2C_CLIENT_MAX; i++) {
if (!adap->clients[i]) list_for_each(item,&adap->clients) {
continue; client = list_entry(item, struct i2c_client, list);
tvmixer_clients(adap->clients[i]); tvmixer_clients(client);
} }
return 0; return 0;
} }
...@@ -252,18 +254,14 @@ static int tvmixer_clients(struct i2c_client *client) ...@@ -252,18 +254,14 @@ static int tvmixer_clients(struct i2c_client *client)
int i,minor; int i,minor;
/* TV card ??? */ /* TV card ??? */
switch (client->adapter->id) { if (!(client->adapter->class & I2C_ADAP_CLASS_TV_ANALOG)) {
case I2C_ALGO_BIT | I2C_HW_B_BT848:
case I2C_ALGO_BIT | I2C_HW_B_RIVA:
/* ok, have a look ... */
break;
default:
/* ignore that one */ /* ignore that one */
if (debug) if (debug)
printk("tvmixer: %s is not a tv card\n", printk("tvmixer: %s is not a tv card\n",
client->adapter->dev.name); client->adapter->dev.name);
return -1; return -1;
} }
if (debug)
printk("tvmixer: debug: %s\n",client->dev.name); printk("tvmixer: debug: %s\n",client->dev.name);
/* unregister ?? */ /* unregister ?? */
......
...@@ -1105,7 +1105,7 @@ static void fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p) ...@@ -1105,7 +1105,7 @@ static void fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p)
i = p->state ? ffz(~p->state) + 1 : 0; i = p->state ? ffz(~p->state) + 1 : 0;
psinfo->pr_state = i; psinfo->pr_state = i;
psinfo->pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i]; psinfo->pr_sname = (i < 0 || i > 5) ? '.' : "RSDTZW"[i];
psinfo->pr_zomb = psinfo->pr_sname == 'Z'; psinfo->pr_zomb = psinfo->pr_sname == 'Z';
psinfo->pr_nice = task_nice(p); psinfo->pr_nice = task_nice(p);
psinfo->pr_flag = p->flags; psinfo->pr_flag = p->flags;
......
...@@ -39,12 +39,6 @@ ...@@ -39,12 +39,6 @@
/* --- General options ------------------------------------------------ */ /* --- General options ------------------------------------------------ */
#define I2C_ALGO_MAX 4 /* control memory consumption */
#define I2C_ADAP_MAX 16
#define I2C_DRIVER_MAX 16
#define I2C_CLIENT_MAX 32
#define I2C_DUMMY_MAX 4
struct i2c_msg; struct i2c_msg;
struct i2c_algorithm; struct i2c_algorithm;
struct i2c_adapter; struct i2c_adapter;
...@@ -131,6 +125,7 @@ struct i2c_driver { ...@@ -131,6 +125,7 @@ struct i2c_driver {
* i2c_attach_client. * i2c_attach_client.
*/ */
int (*attach_adapter)(struct i2c_adapter *); int (*attach_adapter)(struct i2c_adapter *);
int (*detach_adapter)(struct i2c_adapter *);
/* tells the driver that a client is about to be deleted & gives it /* tells the driver that a client is about to be deleted & gives it
* the chance to remove its private data. Also, if the client struct * the chance to remove its private data. Also, if the client struct
...@@ -145,6 +140,7 @@ struct i2c_driver { ...@@ -145,6 +140,7 @@ struct i2c_driver {
int (*command)(struct i2c_client *client,unsigned int cmd, void *arg); int (*command)(struct i2c_client *client,unsigned int cmd, void *arg);
struct device_driver driver; struct device_driver driver;
struct list_head list;
}; };
#define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver)
...@@ -169,6 +165,7 @@ struct i2c_client { ...@@ -169,6 +165,7 @@ struct i2c_client {
int usage_count; /* How many accesses currently */ int usage_count; /* How many accesses currently */
/* to the client */ /* to the client */
struct device dev; /* the device structure */ struct device dev; /* the device structure */
struct list_head list;
}; };
#define to_i2c_client(d) container_of(d, struct i2c_client, dev) #define to_i2c_client(d) container_of(d, struct i2c_client, dev)
...@@ -228,6 +225,7 @@ struct i2c_adapter { ...@@ -228,6 +225,7 @@ struct i2c_adapter {
struct module *owner; struct module *owner;
unsigned int id;/* == is algo->id | hwdep.struct->id, */ unsigned int id;/* == is algo->id | hwdep.struct->id, */
/* for registered values see below */ /* for registered values see below */
unsigned int class;
struct i2c_algorithm *algo;/* the algorithm to access the bus */ struct i2c_algorithm *algo;/* the algorithm to access the bus */
void *algo_data; void *algo_data;
...@@ -236,12 +234,10 @@ struct i2c_adapter { ...@@ -236,12 +234,10 @@ struct i2c_adapter {
int (*client_unregister)(struct i2c_client *); int (*client_unregister)(struct i2c_client *);
/* data fields that are valid for all devices */ /* data fields that are valid for all devices */
struct semaphore bus; struct semaphore bus_lock;
struct semaphore list; struct semaphore clist_lock;
unsigned int flags;/* flags specifying div. data */ unsigned int flags;/* flags specifying div. data */
struct i2c_client *clients[I2C_CLIENT_MAX];
int timeout; int timeout;
int retries; int retries;
struct device dev; /* the adapter device */ struct device dev; /* the adapter device */
...@@ -250,6 +246,10 @@ struct i2c_adapter { ...@@ -250,6 +246,10 @@ struct i2c_adapter {
/* No need to set this when you initialize the adapter */ /* No need to set this when you initialize the adapter */
int inode; int inode;
#endif /* def CONFIG_PROC_FS */ #endif /* def CONFIG_PROC_FS */
int nr;
struct list_head clients;
struct list_head list;
}; };
#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
...@@ -265,7 +265,11 @@ static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data) ...@@ -265,7 +265,11 @@ static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data)
/*flags for the driver struct: */ /*flags for the driver struct: */
#define I2C_DF_NOTIFY 0x01 /* notify on bus (de/a)ttaches */ #define I2C_DF_NOTIFY 0x01 /* notify on bus (de/a)ttaches */
#define I2C_DF_DUMMY 0x02 /* do not connect any clients */ #if 0
/* this flag is gone -- there is a (optional) driver->detach_adapter
* callback now which can be used instead */
# define I2C_DF_DUMMY 0x02
#endif
/*flags for the client struct: */ /*flags for the client struct: */
#define I2C_CLIENT_ALLOW_USE 0x01 /* Client allows access */ #define I2C_CLIENT_ALLOW_USE 0x01 /* Client allows access */
...@@ -275,6 +279,12 @@ static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data) ...@@ -275,6 +279,12 @@ static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data)
#define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */ #define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */
/* Must equal I2C_M_TEN below */ /* Must equal I2C_M_TEN below */
/* i2c adapter classes (bitmask) */
#define I2C_ADAP_CLASS_SMBUS (1<<0) /* lm_sensors, ... */
#define I2C_ADAP_CLASS_TV_ANALOG (1<<1) /* bttv + friends */
#define I2C_ADAP_CLASS_TV_DIGINAL (1<<2) /* dbv cards */
#define I2C_ADAP_CLASS_DDC (1<<3) /* i2c-matroxfb ? */
/* i2c_client_address_data is the struct for holding default client /* i2c_client_address_data is the struct for holding default client
* addresses for a driver and for the parameters supplied on the * addresses for a driver and for the parameters supplied on the
* command line * command line
...@@ -331,6 +341,11 @@ extern struct i2c_client *i2c_get_client(int driver_id, int adapter_id, ...@@ -331,6 +341,11 @@ extern struct i2c_client *i2c_get_client(int driver_id, int adapter_id,
extern int i2c_use_client(struct i2c_client *); extern int i2c_use_client(struct i2c_client *);
extern int i2c_release_client(struct i2c_client *); extern int i2c_release_client(struct i2c_client *);
/* call the i2c_client->command() of all attached clients with
* the given arguments */
extern void i2c_clients_command(struct i2c_adapter *adap,
unsigned int cmd, void *arg);
/* returns -EBUSY if address has been taken, 0 if not. Note that the only /* returns -EBUSY if address has been taken, 0 if not. Note that the only
other place at which this is called is within i2c_attach_client; so other place at which this is called is within i2c_attach_client; so
you can cheat by simply not registering. Not recommended, of course! */ you can cheat by simply not registering. Not recommended, of course! */
...@@ -352,7 +367,8 @@ extern int i2c_control(struct i2c_client *,unsigned int, unsigned long); ...@@ -352,7 +367,8 @@ extern int i2c_control(struct i2c_client *,unsigned int, unsigned long);
* or -1 if the adapter was not registered. * or -1 if the adapter was not registered.
*/ */
extern int i2c_adapter_id(struct i2c_adapter *adap); extern int i2c_adapter_id(struct i2c_adapter *adap);
extern struct i2c_adapter* i2c_get_adapter(int id);
extern void i2c_put_adapter(struct i2c_adapter *adap);
/* Return the functionality mask */ /* Return the functionality mask */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment