aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/pci_hotplug.h
blob: 45fc162cbdc06b0d3d0320c50575b14b5a8b5828 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/*
 * PCI HotPlug Core Functions
 *
 * Copyright (C) 1995,2001 Compaq Computer Corporation
 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
 * Copyright (C) 2001 IBM Corp.
 *
 * All rights reserved.
 *
 * 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
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 * NON INFRINGEMENT.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Send feedback to <kristen.c.accardi@intel.com>
 *
 */
#ifndef _PCI_HOTPLUG_H
#define _PCI_HOTPLUG_H

/* These values come from the PCI Express Spec */
enum pcie_link_width {
	PCIE_LNK_WIDTH_RESRV	= 0x00,
	PCIE_LNK_X1		= 0x01,
	PCIE_LNK_X2		= 0x02,
	PCIE_LNK_X4		= 0x04,
	PCIE_LNK_X8		= 0x08,
	PCIE_LNK_X12		= 0x0C,
	PCIE_LNK_X16		= 0x10,
	PCIE_LNK_X32		= 0x20,
	PCIE_LNK_WIDTH_UNKNOWN  = 0xFF,
};

/**
 * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
 * @owner: The module owner of this structure
 * @mod_name: The module name (KBUILD_MODNAME) of this structure
 * @enable_slot: Called when the user wants to enable a specific pci slot
 * @disable_slot: Called when the user wants to disable a specific pci slot
 * @set_attention_status: Called to set the specific slot's attention LED to
 * the specified value
 * @hardware_test: Called to run a specified hardware test on the specified
 * slot.
 * @get_power_status: Called to get the current power status of a slot.
 * 	If this field is NULL, the value passed in the struct hotplug_slot_info
 * 	will be used when this value is requested by a user.
 * @get_attention_status: Called to get the current attention status of a slot.
 *	If this field is NULL, the value passed in the struct hotplug_slot_info
 *	will be used when this value is requested by a user.
 * @get_latch_status: Called to get the current latch status of a slot.
 *	If this field is NULL, the value passed in the struct hotplug_slot_info
 *	will be used when this value is requested by a user.
 * @get_adapter_status: Called to get see if an adapter is present in the slot or not.
 *	If this field is NULL, the value passed in the struct hotplug_slot_info
 *	will be used when this value is requested by a user.
 *
 * The table of function pointers that is passed to the hotplug pci core by a
 * hotplug pci driver.  These functions are called by the hotplug pci core when
 * the user wants to do something to a specific slot (query it for information,
 * set an LED, enable / disable power, etc.)
 */
struct hotplug_slot_ops {
	struct module *owner;
	const char *mod_name;
	int (*enable_slot)		(struct hotplug_slot *slot);
	int (*disable_slot)		(struct hotplug_slot *slot);
	int (*set_attention_status)	(struct hotplug_slot *slot, u8 value);
	int (*hardware_test)		(struct hotplug_slot *slot, u32 value);
	int (*get_power_status)		(struct hotplug_slot *slot, u8 *value);
	int (*get_attention_status)	(struct hotplug_slot *slot, u8 *value);
	int (*get_latch_status)		(struct hotplug_slot *slot, u8 *value);
	int (*get_adapter_status)	(struct hotplug_slot *slot, u8 *value);
};

/**
 * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot
 * @power_status: if power is enabled or not (1/0)
 * @attention_status: if the attention light is enabled or not (1/0)
 * @latch_status: if the latch (if any) is open or closed (1/0)
 * @adapter_status: if there is a pci board present in the slot or not (1/0)
 *
 * Used to notify the hotplug pci core of the status of a specific slot.
 */
struct hotplug_slot_info {
	u8	power_status;
	u8	attention_status;
	u8	latch_status;
	u8	adapter_status;
};

/**
 * struct hotplug_slot - used to register a physical slot with the hotplug pci core
 * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot
 * @info: pointer to the &struct hotplug_slot_info for the initial values for
 * this slot.
 * @release: called during pci_hp_deregister to free memory allocated in a
 * hotplug_slot structure.
 * @private: used by the hotplug pci controller driver to store whatever it
 * needs.
 */
struct hotplug_slot {
	struct hotplug_slot_ops		*ops;
	struct hotplug_slot_info	*info;
	void (*release) (struct hotplug_slot *slot);
	void				*private;

	/* Variables below this are for use only by the hotplug pci core. */
	struct list_head		slot_list;
	struct pci_slot			*pci_slot;
};
#define to_hotplug_slot(n) container_of(n, struct hotplug_slot, kobj)

static inline const char *hotplug_slot_name(const struct hotplug_slot *slot)
{
	return pci_slot_name(slot->pci_slot);
}

extern int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *pbus,
			     int nr, const char *name,
			     struct module *owner, const char *mod_name);
extern int pci_hp_deregister(struct hotplug_slot *slot);
extern int __must_check pci_hp_change_slot_info	(struct hotplug_slot *slot,
						 struct hotplug_slot_info *info);

/* use a define to avoid include chaining to get THIS_MODULE & friends */
#define pci_hp_register(slot, pbus, devnr, name) \
	__pci_hp_register(slot, pbus, devnr, name, THIS_MODULE, KBUILD_MODNAME)

/* PCI Setting Record (Type 0) */
struct hpp_type0 {
	u32 revision;
	u8  cache_line_size;
	u8  latency_timer;
	u8  enable_serr;
	u8  enable_perr;
};

/* PCI-X Setting Record (Type 1) */
struct hpp_type1 {
	u32 revision;
	u8  max_mem_read;
	u8  avg_max_split;
	u16 tot_max_split;
};

/* PCI Express Setting Record (Type 2) */
struct hpp_type2 {
	u32 revision;
	u32 unc_err_mask_and;
	u32 unc_err_mask_or;
	u32 unc_err_sever_and;
	u32 unc_err_sever_or;
	u32 cor_err_mask_and;
	u32 cor_err_mask_or;
	u32 adv_err_cap_and;
	u32 adv_err_cap_or;
	u16 pci_exp_devctl_and;
	u16 pci_exp_devctl_or;
	u16 pci_exp_lnkctl_and;
	u16 pci_exp_lnkctl_or;
	u32 sec_unc_err_sever_and;
	u32 sec_unc_err_sever_or;
	u32 sec_unc_err_mask_and;
	u32 sec_unc_err_mask_or;
};

struct hotplug_params {
	struct hpp_type0 *t0;		/* Type0: NULL if not available */
	struct hpp_type1 *t1;		/* Type1: NULL if not available */
	struct hpp_type2 *t2;		/* Type2: NULL if not available */
	struct hpp_type0 type0_data;
	struct hpp_type1 type1_data;
	struct hpp_type2 type2_data;
};

#ifdef CONFIG_ACPI
#include <acpi/acpi.h>
#include <acpi/acpi_bus.h>
int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp);
int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags);
int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle);
int acpi_pci_detect_ejectable(acpi_handle handle);
#else
static inline int pci_get_hp_params(struct pci_dev *dev,
				    struct hotplug_params *hpp)
{
	return -ENODEV;
}
#endif

void pci_configure_slot(struct pci_dev *dev);
#endif

); #define GPS_STUB_TEST #ifdef GPS_STUB_TEST int gps_chrdrv_stub_write(const unsigned char*, int); void gps_chrdrv_stub_init(void); #endif /* * header information used by st_kim.c */ /* time in msec to wait for * line discipline to be installed */ #define LDISC_TIME 1000 #define CMD_RESP_TIME 800 #define CMD_WR_TIME 5000 #define MAKEWORD(a, b) ((unsigned short)(((unsigned char)(a)) \ | ((unsigned short)((unsigned char)(b))) << 8)) #define GPIO_HIGH 1 #define GPIO_LOW 0 /* the Power-On-Reset logic, requires to attempt * to download firmware onto chip more than once * since the self-test for chip takes a while */ #define POR_RETRY_COUNT 5 /** * struct chip_version - save the chip version */ struct chip_version { unsigned short full; unsigned short chip; unsigned short min_ver; unsigned short maj_ver; }; #define UART_DEV_NAME_LEN 32 /** * struct kim_data_s - the KIM internal data, embedded as the * platform's drv data. One for each ST device in the system. * @uim_pid: KIM needs to communicate with UIM to request to install * the ldisc by opening UART when protocol drivers register. * @kim_pdev: the platform device added in one of the board-XX.c file * in arch/XX/ directory, 1 for each ST device. * @kim_rcvd: completion handler to notify when data was received, * mainly used during fw download, which involves multiple send/wait * for each of the HCI-VS commands. * @ldisc_installed: completion handler to notify that the UIM accepted * the request to install ldisc, notify from tty_open which suggests * the ldisc was properly installed. * @resp_buffer: data buffer for the .bts fw file name. * @fw_entry: firmware class struct to request/release the fw. * @rx_state: the rx state for kim's receive func during fw download. * @rx_count: the rx count for the kim's receive func during fw download. * @rx_skb: all of fw data might not come at once, and hence data storage for * whole of the fw response, only HCI_EVENTs and hence diff from ST's * response. * @core_data: ST core's data, which mainly is the tty's disc_data * @version: chip version available via a sysfs entry. * */ struct kim_data_s { long uim_pid; struct platform_device *kim_pdev; struct completion kim_rcvd, ldisc_installed; char resp_buffer[30]; const struct firmware *fw_entry; long nshutdown; unsigned long rx_state; unsigned long rx_count; struct sk_buff *rx_skb; struct st_data_s *core_data; struct chip_version version; unsigned char ldisc_install; unsigned char dev_name[UART_DEV_NAME_LEN]; unsigned char flow_cntrl; unsigned long baud_rate; }; /** * functions called when 1 of the protocol drivers gets * registered, these need to communicate with UIM to request * ldisc installed, read chip_version, download relevant fw */ long st_kim_start(void *); long st_kim_stop(void *); void st_kim_complete(void *); void kim_st_list_protocols(struct st_data_s *, void *); void st_kim_recv(void *, const unsigned char *, long); /* * BTS headers */ #define ACTION_SEND_COMMAND 1 #define ACTION_WAIT_EVENT 2 #define ACTION_SERIAL 3 #define ACTION_DELAY 4 #define ACTION_RUN_SCRIPT 5 #define ACTION_REMARKS 6 /** * struct bts_header - the fw file is NOT binary which can * be sent onto TTY as is. The .bts is more a script * file which has different types of actions. * Each such action needs to be parsed by the KIM and * relevant procedure to be called. */ struct bts_header { u32 magic; u32 version; u8 future[24]; u8 actions[0]; } __attribute__ ((packed)); /** * struct bts_action - Each .bts action has its own type of * data. */ struct bts_action { u16 type; u16 size; u8 data[0]; } __attribute__ ((packed)); struct bts_action_send { u8 data[0]; } __attribute__ ((packed)); struct bts_action_wait { u32 msec; u32 size; u8 data[0]; } __attribute__ ((packed)); struct bts_action_delay { u32 msec; } __attribute__ ((packed)); struct bts_action_serial { u32 baud; u32 flow_control; } __attribute__ ((packed)); /** * struct hci_command - the HCI-VS for intrepreting * the change baud rate of host-side UART, which * needs to be ignored, since UIM would do that * when it receives request from KIM for ldisc installation. */ struct hci_command { u8 prefix; u16 opcode; u8 plen; u32 speed; } __attribute__ ((packed)); /* * header information used by st_ll.c */ /* ST LL receiver states */ #define ST_W4_PACKET_TYPE 0 #define ST_W4_HEADER 1 #define ST_W4_DATA 2 /* ST LL state machines */ #define ST_LL_ASLEEP 0 #define ST_LL_ASLEEP_TO_AWAKE 1 #define ST_LL_AWAKE 2 #define ST_LL_AWAKE_TO_ASLEEP 3 #define ST_LL_INVALID 4 /* different PM notifications coming from chip */ #define LL_SLEEP_IND 0x30 #define LL_SLEEP_ACK 0x31 #define LL_WAKE_UP_IND 0x32 #define LL_WAKE_UP_ACK 0x33 /* initialize and de-init ST LL */ long st_ll_init(struct st_data_s *); long st_ll_deinit(struct st_data_s *); /** * enable/disable ST LL along with KIM start/stop * called by ST Core */ void st_ll_enable(struct st_data_s *); void st_ll_disable(struct st_data_s *); /** * various funcs used by ST core to set/get the various PM states * of the chip. */ unsigned long st_ll_getstate(struct st_data_s *); unsigned long st_ll_sleep_state(struct st_data_s *, unsigned char); void st_ll_wakeup(struct st_data_s *); /* * header information used by st_core.c for FM and GPS * packet parsing, the bluetooth headers are already available * at net/bluetooth/ */ struct fm_event_hdr { u8 plen; } __attribute__ ((packed)); #define FM_MAX_FRAME_SIZE 0xFF /* TODO: */ #define FM_EVENT_HDR_SIZE 1 /* size of fm_event_hdr */ #define ST_FM_CH8_PKT 0x8 /* gps stuff */ struct gps_event_hdr { u8 opcode; u16 plen; } __attribute__ ((packed)); /** * struct ti_st_plat_data - platform data shared between ST driver and * platform specific board file which adds the ST device. * @nshutdown_gpio: Host's GPIO line to which chip's BT_EN is connected. * @dev_name: The UART/TTY name to which chip is interfaced. (eg: /dev/ttyS1) * @flow_cntrl: Should always be 1, since UART's CTS/RTS is used for PM * purposes. * @baud_rate: The baud rate supported by the Host UART controller, this will * be shared across with the chip via a HCI VS command from User-Space Init * Mgr application. * @suspend: * @resume: legacy PM routines hooked to platform specific board file, so as * to take chip-host interface specific action. * @chip_enable: * @chip_disable: Platform/Interface specific mux mode setting, GPIO * configuring, Host side PM disabling etc.. can be done here. * @chip_asleep: * @chip_awake: Chip specific deep sleep states is communicated to Host * specific board-xx.c to take actions such as cut UART clocks when chip * asleep or run host faster when chip awake etc.. * */ struct ti_st_plat_data { long nshutdown_gpio; unsigned char dev_name[UART_DEV_NAME_LEN]; /* uart name */ unsigned char flow_cntrl; /* flow control flag */ unsigned long baud_rate; int (*suspend)(struct platform_device *, pm_message_t); int (*resume)(struct platform_device *); int (*chip_enable) (struct kim_data_s *); int (*chip_disable) (struct kim_data_s *); int (*chip_asleep) (struct kim_data_s *); int (*chip_awake) (struct kim_data_s *); }; #endif /* TI_WILINK_ST_H */