1
0
Fork 0

Merge v3.6-rc3 into 'char-misc-next'

This resolves a conflict in:
	drivers/misc/mei/interrupt.c

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
hifive-unleashed-5.1
Greg Kroah-Hartman 2012-08-27 09:09:07 -07:00
commit 7da59d2fe3
21 changed files with 409 additions and 377 deletions

View File

@ -0,0 +1,22 @@
w1-gpio devicetree bindings
Required properties:
- compatible: "w1-gpio"
- gpios: one or two GPIO specs:
- the first one is used as data I/O pin
- the second one is optional. If specified, it is used as
enable pin for an external pin pullup.
Optional properties:
- linux,open-drain: if specified, the data pin is considered in
open-drain mode.
Examples:
onewire@0 {
compatible = "w1-gpio";
gpios = <&gpio 126 0>, <&gpio 105 0>;
};

View File

@ -784,8 +784,10 @@ static int __init tlclk_init(void)
}
tlclk_major = ret;
alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL);
if (!alarm_events)
if (!alarm_events) {
ret = -ENOMEM;
goto out1;
}
/* Read telecom clock IRQ number (Set by BIOS) */
if (!request_region(TLCLK_BASE, 8, "telco_clock")) {

View File

@ -57,12 +57,6 @@ static int bmp085_i2c_remove(struct i2c_client *client)
return bmp085_remove(&client->dev);
}
static const struct of_device_id bmp085_of_match[] = {
{ .compatible = "bosch,bmp085", },
{ },
};
MODULE_DEVICE_TABLE(of, bmp085_of_match);
static const struct i2c_device_id bmp085_id[] = {
{ BMP085_NAME, 0 },
{ "bmp180", 0 },
@ -74,7 +68,6 @@ static struct i2c_driver bmp085_i2c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = BMP085_NAME,
.of_match_table = bmp085_of_match
},
.id_table = bmp085_id,
.probe = bmp085_i2c_probe,

View File

@ -978,7 +978,6 @@ static int fpga_of_probe(struct platform_device *op)
dev_set_drvdata(priv->dev, priv);
dma_cap_zero(mask);
dma_cap_set(DMA_MEMCPY, mask);
dma_cap_set(DMA_INTERRUPT, mask);
dma_cap_set(DMA_SLAVE, mask);
dma_cap_set(DMA_SG, mask);

View File

@ -666,7 +666,7 @@ static int data_submit_dma(struct fpga_device *priv, struct data_buf *buf)
src = SYS_FPGA_BLOCK;
tx = chan->device->device_prep_dma_memcpy(chan, dst, src,
REG_BLOCK_SIZE,
DMA_PREP_INTERRUPT);
0);
if (!tx) {
dev_err(priv->dev, "unable to prep SYS-FPGA DMA\n");
return -ENOMEM;

View File

@ -40,46 +40,45 @@
/*
* MEI device IDs
*/
#define MEI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */
#define MEI_DEV_ID_82G35 0x2984 /* 82G35 Express */
#define MEI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */
#define MEI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */
#define MEI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */
#define MEI_DEV_ID_82G35 0x2984 /* 82G35 Express */
#define MEI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */
#define MEI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */
#define MEI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */
#define MEI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */
#define MEI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */
#define MEI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */
#define MEI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */
#define MEI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */
#define MEI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */
#define MEI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */
#define MEI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */
#define MEI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */
#define MEI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */
#define MEI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */
#define MEI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */
#define MEI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */
#define MEI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */
#define MEI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */
#define MEI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */
#define MEI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */
#define MEI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */
#define MEI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */
#define MEI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */
#define MEI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */
#define MEI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */
#define MEI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */
#define MEI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */
#define MEI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */
#define MEI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */
#define MEI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */
#define MEI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */
#define MEI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */
#define MEI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */
#define MEI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */
#define MEI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */
#define MEI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */
#define MEI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */
#define MEI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */
#define MEI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */
#define MEI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */
#define MEI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */
#define MEI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */
#define MEI_DEV_ID_IBXPK_1 0x3B64 /* Calpella */
#define MEI_DEV_ID_IBXPK_2 0x3B65 /* Calpella */
#define MEI_DEV_ID_IBXPK_1 0x3B64 /* Calpella */
#define MEI_DEV_ID_IBXPK_2 0x3B65 /* Calpella */
#define MEI_DEV_ID_CPT_1 0x1C3A /* Cougerpoint */
#define MEI_DEV_ID_PBG_1 0x1D3A /* PBG */
#define MEI_DEV_ID_PPT_1 0x1E3A /* Pantherpoint PPT */
#define MEI_DEV_ID_PPT_2 0x1CBA /* Pantherpoint PPT */
#define MEI_DEV_ID_PPT_3 0x1DBA /* Pantherpoint PPT */
#define MEI_DEV_ID_CPT_1 0x1C3A /* Couger Point */
#define MEI_DEV_ID_PBG_1 0x1D3A /* C600/X79 Patsburg */
#define MEI_DEV_ID_PPT_1 0x1E3A /* Panther Point */
#define MEI_DEV_ID_PPT_2 0x1CBA /* Panther Point */
#define MEI_DEV_ID_PPT_3 0x1DBA /* Panther Point */
/*
* MEI HW Section

View File

@ -24,6 +24,25 @@
#include "interface.h"
#include <linux/mei.h>
const char *mei_dev_state_str(int state)
{
#define MEI_DEV_STATE(state) case MEI_DEV_##state: return #state
switch (state) {
MEI_DEV_STATE(INITIALIZING);
MEI_DEV_STATE(INIT_CLIENTS);
MEI_DEV_STATE(ENABLED);
MEI_DEV_STATE(RESETING);
MEI_DEV_STATE(DISABLED);
MEI_DEV_STATE(RECOVERING_FROM_RESET);
MEI_DEV_STATE(POWER_DOWN);
MEI_DEV_STATE(POWER_UP);
default:
return "unkown";
}
#undef MEI_DEV_STATE
}
const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac,
0xa8, 0x46, 0xe0, 0xff, 0x65,
0x81, 0x4c);
@ -123,7 +142,7 @@ struct mei_device *mei_device_init(struct pci_dev *pdev)
mutex_init(&dev->device_lock);
init_waitqueue_head(&dev->wait_recvd_msg);
init_waitqueue_head(&dev->wait_stop_wd);
dev->mei_state = MEI_INITIALIZING;
dev->dev_state = MEI_DEV_INITIALIZING;
dev->iamthif_state = MEI_IAMTHIF_IDLE;
dev->wd_interface_reg = false;
@ -182,7 +201,7 @@ int mei_hw_init(struct mei_device *dev)
}
if (err <= 0 && !dev->recvd_msg) {
dev->mei_state = MEI_DISABLED;
dev->dev_state = MEI_DEV_DISABLED;
dev_dbg(&dev->pdev->dev,
"wait_event_interruptible_timeout failed"
"on wait for ME to turn on ME_RDY.\n");
@ -192,7 +211,7 @@ int mei_hw_init(struct mei_device *dev)
if (!(((dev->host_hw_state & H_RDY) == H_RDY) &&
((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) {
dev->mei_state = MEI_DISABLED;
dev->dev_state = MEI_DEV_DISABLED;
dev_dbg(&dev->pdev->dev,
"host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
dev->host_hw_state, dev->me_hw_state);
@ -258,15 +277,15 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
struct mei_cl_cb *cb_next = NULL;
bool unexpected;
if (dev->mei_state == MEI_RECOVERING_FROM_RESET) {
if (dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) {
dev->need_reset = true;
return;
}
unexpected = (dev->mei_state != MEI_INITIALIZING &&
dev->mei_state != MEI_DISABLED &&
dev->mei_state != MEI_POWER_DOWN &&
dev->mei_state != MEI_POWER_UP);
unexpected = (dev->dev_state != MEI_DEV_INITIALIZING &&
dev->dev_state != MEI_DEV_DISABLED &&
dev->dev_state != MEI_DEV_POWER_DOWN &&
dev->dev_state != MEI_DEV_POWER_UP);
dev->host_hw_state = mei_hcsr_read(dev);
@ -285,10 +304,10 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
dev->need_reset = false;
if (dev->mei_state != MEI_INITIALIZING) {
if (dev->mei_state != MEI_DISABLED &&
dev->mei_state != MEI_POWER_DOWN)
dev->mei_state = MEI_RESETING;
if (dev->dev_state != MEI_DEV_INITIALIZING) {
if (dev->dev_state != MEI_DEV_DISABLED &&
dev->dev_state != MEI_DEV_POWER_DOWN)
dev->dev_state = MEI_DEV_RESETING;
list_for_each_entry_safe(cl_pos,
cl_next, &dev->file_list, link) {
@ -311,7 +330,6 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
dev->me_clients_num = 0;
dev->rd_msg_hdr = 0;
dev->stop = false;
dev->wd_pending = false;
/* update the state of the registers after reset */
@ -322,7 +340,8 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
dev->host_hw_state, dev->me_hw_state);
if (unexpected)
dev_warn(&dev->pdev->dev, "unexpected reset.\n");
dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
mei_dev_state_str(dev->dev_state));
/* Wake up all readings so they can be interrupted */
list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
@ -371,7 +390,7 @@ void mei_host_start_message(struct mei_device *dev)
if (mei_write_message(dev, mei_hdr, (unsigned char *)host_start_req,
mei_hdr->length)) {
dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n");
dev->mei_state = MEI_RESETING;
dev->dev_state = MEI_DEV_RESETING;
mei_reset(dev, 1);
}
dev->init_clients_state = MEI_START_MESSAGE;
@ -403,7 +422,7 @@ void mei_host_enum_clients_message(struct mei_device *dev)
host_enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;
if (mei_write_message(dev, mei_hdr, (unsigned char *)host_enum_req,
mei_hdr->length)) {
dev->mei_state = MEI_RESETING;
dev->dev_state = MEI_DEV_RESETING;
dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
mei_reset(dev, 1);
}
@ -444,7 +463,7 @@ void mei_allocate_me_clients_storage(struct mei_device *dev)
sizeof(struct mei_me_client), GFP_KERNEL);
if (!clients) {
dev_dbg(&dev->pdev->dev, "memory allocation for ME clients failed.\n");
dev->mei_state = MEI_RESETING;
dev->dev_state = MEI_DEV_RESETING;
mei_reset(dev, 1);
return ;
}
@ -490,7 +509,7 @@ int mei_host_client_properties(struct mei_device *dev)
if (mei_write_message(dev, mei_header,
(unsigned char *)host_cli_req,
mei_header->length)) {
dev->mei_state = MEI_RESETING;
dev->dev_state = MEI_DEV_RESETING;
dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
mei_reset(dev, 1);
return -EIO;
@ -522,12 +541,12 @@ void mei_cl_init(struct mei_cl *priv, struct mei_device *dev)
priv->dev = dev;
}
int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid)
int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid)
{
int i, res = -1;
int i, res = -ENOENT;
for (i = 0; i < dev->me_clients_num; ++i)
if (uuid_le_cmp(cuuid,
if (uuid_le_cmp(*cuuid,
dev->me_clients[i].props.protocol_name) == 0) {
res = i;
break;
@ -538,35 +557,35 @@ int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid)
/**
* mei_find_me_client_update_filext - searches for ME client guid
* mei_me_cl_update_filext - searches for ME client guid
* sets client_id in mei_file_private if found
* @dev: the device structure
* @priv: private file structure to set client_id in
* @cguid: searched guid of ME client
* @cl: private file structure to set client_id in
* @cuuid: searched uuid of ME client
* @client_id: id of host client to be set in file private structure
*
* returns ME client index
*/
u8 mei_find_me_client_update_filext(struct mei_device *dev, struct mei_cl *priv,
const uuid_le *cguid, u8 client_id)
int mei_me_cl_update_filext(struct mei_device *dev, struct mei_cl *cl,
const uuid_le *cuuid, u8 host_cl_id)
{
int i;
if (!dev || !priv || !cguid)
return 0;
if (!dev || !cl || !cuuid)
return -EINVAL;
/* check for valid client id */
i = mei_find_me_client_index(dev, *cguid);
i = mei_me_cl_by_uuid(dev, cuuid);
if (i >= 0) {
priv->me_client_id = dev->me_clients[i].client_id;
priv->state = MEI_FILE_CONNECTING;
priv->host_client_id = client_id;
cl->me_client_id = dev->me_clients[i].client_id;
cl->state = MEI_FILE_CONNECTING;
cl->host_client_id = host_cl_id;
list_add_tail(&priv->link, &dev->file_list);
list_add_tail(&cl->link, &dev->file_list);
return (u8)i;
}
return 0;
return -ENOENT;
}
/**
@ -577,16 +596,16 @@ u8 mei_find_me_client_update_filext(struct mei_device *dev, struct mei_cl *priv,
*/
void mei_host_init_iamthif(struct mei_device *dev)
{
u8 i;
int i;
unsigned char *msg_buf;
mei_cl_init(&dev->iamthif_cl, dev);
dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
/* find ME amthi client */
i = mei_find_me_client_update_filext(dev, &dev->iamthif_cl,
i = mei_me_cl_update_filext(dev, &dev->iamthif_cl,
&mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID);
if (dev->iamthif_cl.state != MEI_FILE_CONNECTING) {
if (i < 0) {
dev_dbg(&dev->pdev->dev, "failed to find iamthif client.\n");
return;
}

View File

@ -23,14 +23,6 @@
#include "mei_dev.h"
#define AMT_WD_DEFAULT_TIMEOUT 120 /* seconds */
#define AMT_WD_MIN_TIMEOUT 120 /* seconds */
#define AMT_WD_MAX_TIMEOUT 65535 /* seconds */
#define MEI_WATCHDOG_DATA_SIZE 16
#define MEI_START_WD_DATA_SIZE 20
#define MEI_WD_PARAMS_SIZE 4
void mei_read_slots(struct mei_device *dev,
unsigned char *buffer,
@ -64,7 +56,7 @@ int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl);
int mei_wd_send(struct mei_device *dev);
int mei_wd_stop(struct mei_device *dev, bool preserve);
int mei_wd_stop(struct mei_device *dev);
int mei_wd_host_init(struct mei_device *dev);
/*
* mei_watchdog_register - Registering watchdog interface

View File

@ -633,7 +633,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
if (version_res->host_version_supported) {
dev->version.major_version = HBM_MAJOR_VERSION;
dev->version.minor_version = HBM_MINOR_VERSION;
if (dev->mei_state == MEI_INIT_CLIENTS &&
if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
dev->init_clients_state == MEI_START_MESSAGE) {
dev->init_clients_timer = 0;
mei_host_enum_clients_message(dev);
@ -707,7 +707,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
dev->me_clients[dev->me_client_presentation_num].props
= props_res->client_properties;
if (dev->mei_state == MEI_INIT_CLIENTS &&
if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
dev->init_clients_state ==
MEI_CLIENT_PROPERTIES_MESSAGE) {
dev->me_client_index++;
@ -734,7 +734,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
* Client ID 2 - Reserved for AMTHI
*/
bitmap_set(dev->host_clients_map, 0, 3);
dev->mei_state = MEI_ENABLED;
dev->dev_state = MEI_DEV_ENABLED;
/* if wd initialization fails, initialization the AMTHI client,
* otherwise the AMTHI client will be initialized after the WD client connect response
@ -759,7 +759,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
case HOST_ENUM_RES_CMD:
enum_res = (struct hbm_host_enum_response *) mei_msg;
memcpy(dev->me_clients_map, enum_res->valid_addresses, 32);
if (dev->mei_state == MEI_INIT_CLIENTS &&
if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) {
dev->init_clients_timer = 0;
dev->me_client_presentation_num = 0;
@ -776,7 +776,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
break;
case HOST_STOP_RES_CMD:
dev->mei_state = MEI_DISABLED;
dev->dev_state = MEI_DEV_DISABLED;
dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n");
mei_reset(dev, 1);
break;
@ -1224,10 +1224,9 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
}
}
if (dev->stop && !dev->wd_pending) {
dev->wd_stopped = true;
if (dev->wd_state == MEI_WD_STOPPING) {
dev->wd_state = MEI_WD_IDLE;
wake_up_interruptible(&dev->wait_stop_wd);
return 0;
}
if (dev->extra_write_index) {
@ -1240,7 +1239,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
*slots -= dev->extra_write_index;
dev->extra_write_index = 0;
}
if (dev->mei_state == MEI_ENABLED) {
if (dev->dev_state == MEI_DEV_ENABLED) {
if (dev->wd_pending &&
mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
if (mei_wd_send(dev))
@ -1250,14 +1249,12 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
dev->wd_pending = false;
if (dev->wd_timeout)
*slots -= mei_data2slots(MEI_START_WD_DATA_SIZE);
if (dev->wd_state == MEI_WD_RUNNING)
*slots -= mei_data2slots(MEI_WD_START_MSG_SIZE);
else
*slots -= mei_data2slots(MEI_WD_PARAMS_SIZE);
*slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE);
}
}
if (dev->stop)
return -ENODEV;
/* complete control write list CB */
dev_dbg(&dev->pdev->dev, "complete control write list cb.\n");
@ -1361,8 +1358,8 @@ void mei_timer(struct work_struct *work)
mutex_lock(&dev->device_lock);
if (dev->mei_state != MEI_ENABLED) {
if (dev->mei_state == MEI_INIT_CLIENTS) {
if (dev->dev_state != MEI_DEV_ENABLED) {
if (dev->dev_state == MEI_DEV_INIT_CLIENTS) {
if (dev->init_clients_timer) {
if (--dev->init_clients_timer == 0) {
dev_dbg(&dev->pdev->dev, "IMEI reset due to init clients timeout ,init clients state = %d.\n",
@ -1484,8 +1481,8 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
/* check if ME wants a reset */
if ((dev->me_hw_state & ME_RDY_HRA) == 0 &&
dev->mei_state != MEI_RESETING &&
dev->mei_state != MEI_INITIALIZING) {
dev->dev_state != MEI_DEV_RESETING &&
dev->dev_state != MEI_DEV_INITIALIZING) {
dev_dbg(&dev->pdev->dev, "FW not ready.\n");
mei_reset(dev, 1);
mutex_unlock(&dev->device_lock);
@ -1498,7 +1495,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
dev_dbg(&dev->pdev->dev, "we need to start the dev.\n");
dev->host_hw_state |= (H_IE | H_IG | H_RDY);
mei_hcsr_set(dev);
dev->mei_state = MEI_INIT_CLIENTS;
dev->dev_state = MEI_DEV_INIT_CLIENTS;
dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n");
/* link is established
* start sending messages.

View File

@ -38,7 +38,31 @@
#include <linux/mei.h>
#include "interface.h"
/**
* mei_me_cl_by_id return index to me_clients for client_id
*
* @dev: the device structure
* @client_id: me client id
*
* Locking: called under "dev->device_lock" lock
*
* returns index on success, -ENOENT on failure.
*/
int mei_me_cl_by_id(struct mei_device *dev, u8 client_id)
{
int i;
for (i = 0; i < dev->me_clients_num; i++)
if (dev->me_clients[i].client_id == client_id)
break;
if (WARN_ON(dev->me_clients[i].client_id != client_id))
return -ENOENT;
if (i == dev->me_clients_num)
return -ENOENT;
return i;
}
/**
* mei_ioctl_connect_client - the connect to fw client IOCTL function
@ -84,7 +108,7 @@ int mei_ioctl_connect_client(struct file *file,
cb->major_file_operations = MEI_IOCTL;
if (dev->mei_state != MEI_ENABLED) {
if (dev->dev_state != MEI_DEV_ENABLED) {
rets = -ENODEV;
goto end;
}
@ -95,7 +119,7 @@ int mei_ioctl_connect_client(struct file *file,
}
/* find ME client we're trying to connect to */
i = mei_find_me_client_index(dev, data->in_client_uuid);
i = mei_me_cl_by_uuid(dev, &data->in_client_uuid);
if (i >= 0 && !dev->me_clients[i].props.fixed_address) {
cl->me_client_id = dev->me_clients[i].client_id;
cl->state = MEI_FILE_CONNECTING;
@ -273,19 +297,12 @@ int amthi_read(struct mei_device *dev, struct file *file,
return -ETIMEDOUT;
}
for (i = 0; i < dev->me_clients_num; i++) {
if (dev->me_clients[i].client_id ==
dev->iamthif_cl.me_client_id)
break;
}
i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id);
if (i == dev->me_clients_num) {
if (i < 0) {
dev_dbg(&dev->pdev->dev, "amthi client not found.\n");
return -ENODEV;
}
if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id))
return -ENODEV;
dev_dbg(&dev->pdev->dev, "checking amthi data\n");
cb = find_amthi_read_list_entry(dev, file);
@ -316,8 +333,7 @@ int amthi_read(struct mei_device *dev, struct file *file,
dev->iamthif_timer = 0;
if (cb) {
timeout = cb->read_time +
msecs_to_jiffies(IAMTHIF_READ_TIMER);
timeout = cb->read_time + msecs_to_jiffies(IAMTHIF_READ_TIMER);
dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n",
timeout);
@ -386,7 +402,7 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl)
if (cl->state != MEI_FILE_CONNECTED)
return -ENODEV;
if (dev->mei_state != MEI_ENABLED)
if (dev->dev_state != MEI_DEV_ENABLED)
return -ENODEV;
dev_dbg(&dev->pdev->dev, "check if read is pending.\n");
@ -401,19 +417,8 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl)
dev_dbg(&dev->pdev->dev, "allocation call back successful. host client = %d, ME client = %d\n",
cl->host_client_id, cl->me_client_id);
for (i = 0; i < dev->me_clients_num; i++) {
if (dev->me_clients[i].client_id == cl->me_client_id)
break;
}
if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) {
rets = -ENODEV;
goto unlock;
}
if (i == dev->me_clients_num) {
i = mei_me_cl_by_id(dev, cl->me_client_id);
if (i < 0) {
rets = -ENODEV;
goto unlock;
}

View File

@ -41,8 +41,6 @@
#include <linux/mei.h>
#include "interface.h"
static const char mei_driver_name[] = "mei";
/* The device pointer */
/* Currently this driver works as long as there is only a single AMT device. */
struct pci_dev *mei_device;
@ -234,9 +232,9 @@ static int mei_open(struct inode *inode, struct file *file)
goto out_unlock;
err = -ENODEV;
if (dev->mei_state != MEI_ENABLED) {
dev_dbg(&dev->pdev->dev, "mei_state != MEI_ENABLED mei_state= %d\n",
dev->mei_state);
if (dev->dev_state != MEI_DEV_ENABLED) {
dev_dbg(&dev->pdev->dev, "dev_state != MEI_ENABLED dev_state = %s\n",
mei_dev_state_str(dev->dev_state));
goto out_unlock;
}
err = -EMFILE;
@ -386,17 +384,16 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
dev = cl->dev;
mutex_lock(&dev->device_lock);
if (dev->mei_state != MEI_ENABLED) {
if (dev->dev_state != MEI_DEV_ENABLED) {
rets = -ENODEV;
goto out;
}
if ((cl->sm_state & MEI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) {
/* Do not allow to read watchdog client */
i = mei_find_me_client_index(dev, mei_wd_guid);
i = mei_me_cl_by_uuid(dev, &mei_wd_guid);
if (i >= 0) {
struct mei_me_client *me_client = &dev->me_clients[i];
if (cl->me_client_id == me_client->client_id) {
rets = -EBADF;
goto out;
@ -541,7 +538,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
mutex_lock(&dev->device_lock);
if (dev->mei_state != MEI_ENABLED) {
if (dev->dev_state != MEI_DEV_ENABLED) {
mutex_unlock(&dev->device_lock);
return -ENODEV;
}
@ -616,26 +613,16 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
rets = -ENOMEM;
goto unlock_dev;
}
if (dev->mei_state != MEI_ENABLED) {
if (dev->dev_state != MEI_DEV_ENABLED) {
rets = -ENODEV;
goto unlock_dev;
}
for (i = 0; i < dev->me_clients_num; i++) {
if (dev->me_clients[i].client_id ==
dev->iamthif_cl.me_client_id)
break;
}
if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) {
i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id);
if (i < 0) {
rets = -ENODEV;
goto unlock_dev;
}
if (i == dev->me_clients_num ||
(dev->me_clients[i].client_id !=
dev->iamthif_cl.me_client_id)) {
rets = -ENODEV;
goto unlock_dev;
} else if (length > dev->me_clients[i].props.max_msg_length ||
if (length > dev->me_clients[i].props.max_msg_length ||
length <= 0) {
rets = -EMSGSIZE;
goto unlock_dev;
@ -688,16 +675,8 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
cl->me_client_id);
goto unlock_dev;
}
for (i = 0; i < dev->me_clients_num; i++) {
if (dev->me_clients[i].client_id ==
cl->me_client_id)
break;
}
if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) {
rets = -ENODEV;
goto unlock_dev;
}
if (i == dev->me_clients_num) {
i = mei_me_cl_by_id(dev, cl->me_client_id);
if (i < 0) {
rets = -ENODEV;
goto unlock_dev;
}
@ -790,7 +769,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data)
dev_dbg(&dev->pdev->dev, "IOCTL cmd = 0x%x", cmd);
mutex_lock(&dev->device_lock);
if (dev->mei_state != MEI_ENABLED) {
if (dev->dev_state != MEI_DEV_ENABLED) {
rets = -ENODEV;
goto out;
}
@ -869,7 +848,7 @@ static unsigned int mei_poll(struct file *file, poll_table *wait)
mutex_lock(&dev->device_lock);
if (dev->mei_state != MEI_ENABLED)
if (dev->dev_state != MEI_DEV_ENABLED)
goto out;
@ -979,7 +958,7 @@ static int __devinit mei_probe(struct pci_dev *pdev,
/* set PCI host mastering */
pci_set_master(pdev);
/* pci request regions for mei driver */
err = pci_request_regions(pdev, mei_driver_name);
err = pci_request_regions(pdev, KBUILD_MODNAME);
if (err) {
dev_err(&pdev->dev, "failed to get pci regions.\n");
goto disable_device;
@ -1004,12 +983,12 @@ static int __devinit mei_probe(struct pci_dev *pdev,
err = request_threaded_irq(pdev->irq,
NULL,
mei_interrupt_thread_handler,
IRQF_ONESHOT, mei_driver_name, dev);
IRQF_ONESHOT, KBUILD_MODNAME, dev);
else
err = request_threaded_irq(pdev->irq,
mei_interrupt_quick_handler,
mei_interrupt_thread_handler,
IRQF_SHARED, mei_driver_name, dev);
IRQF_SHARED, KBUILD_MODNAME, dev);
if (err) {
dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n",
@ -1081,7 +1060,9 @@ static void __devexit mei_remove(struct pci_dev *pdev)
mutex_lock(&dev->device_lock);
mei_wd_stop(dev, false);
cancel_delayed_work(&dev->timer_work);
mei_wd_stop(dev);
mei_device = NULL;
@ -1136,12 +1117,15 @@ static int mei_pci_suspend(struct device *device)
if (!dev)
return -ENODEV;
mutex_lock(&dev->device_lock);
cancel_delayed_work(&dev->timer_work);
/* Stop watchdog if exists */
err = mei_wd_stop(dev, true);
err = mei_wd_stop(dev);
/* Set new mei state */
if (dev->mei_state == MEI_ENABLED ||
dev->mei_state == MEI_RECOVERING_FROM_RESET) {
dev->mei_state = MEI_POWER_DOWN;
if (dev->dev_state == MEI_DEV_ENABLED ||
dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) {
dev->dev_state = MEI_DEV_POWER_DOWN;
mei_reset(dev, 0);
}
mutex_unlock(&dev->device_lock);
@ -1169,12 +1153,12 @@ static int mei_pci_resume(struct device *device)
err = request_threaded_irq(pdev->irq,
NULL,
mei_interrupt_thread_handler,
IRQF_ONESHOT, mei_driver_name, dev);
IRQF_ONESHOT, KBUILD_MODNAME, dev);
else
err = request_threaded_irq(pdev->irq,
mei_interrupt_quick_handler,
mei_interrupt_thread_handler,
IRQF_SHARED, mei_driver_name, dev);
IRQF_SHARED, KBUILD_MODNAME, dev);
if (err) {
dev_err(&pdev->dev, "request_threaded_irq failed: irq = %d.\n",
@ -1183,7 +1167,7 @@ static int mei_pci_resume(struct device *device)
}
mutex_lock(&dev->device_lock);
dev->mei_state = MEI_POWER_UP;
dev->dev_state = MEI_DEV_POWER_UP;
mei_reset(dev, 1);
mutex_unlock(&dev->device_lock);
@ -1201,7 +1185,7 @@ static SIMPLE_DEV_PM_OPS(mei_pm_ops, mei_pci_suspend, mei_pci_resume);
* PCI driver structure
*/
static struct pci_driver mei_driver = {
.name = mei_driver_name,
.name = KBUILD_MODNAME,
.id_table = mei_pci_tbl,
.probe = mei_probe,
.remove = __devexit_p(mei_remove),

View File

@ -25,9 +25,16 @@
/*
* watch dog definition
*/
#define MEI_WATCHDOG_DATA_SIZE 16
#define MEI_START_WD_DATA_SIZE 20
#define MEI_WD_PARAMS_SIZE 4
#define MEI_WD_HDR_SIZE 4
#define MEI_WD_STOP_MSG_SIZE MEI_WD_HDR_SIZE
#define MEI_WD_START_MSG_SIZE (MEI_WD_HDR_SIZE + 16)
#define MEI_WD_DEFAULT_TIMEOUT 120 /* seconds */
#define MEI_WD_MIN_TIMEOUT 120 /* seconds */
#define MEI_WD_MAX_TIMEOUT 65535 /* seconds */
#define MEI_WD_STOP_TIMEOUT 10 /* msecs */
#define MEI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0)
#define MEI_RD_MSG_BUF_SIZE (128 * sizeof(u32))
@ -78,17 +85,19 @@ enum file_state {
};
/* MEI device states */
enum mei_states {
MEI_INITIALIZING = 0,
MEI_INIT_CLIENTS,
MEI_ENABLED,
MEI_RESETING,
MEI_DISABLED,
MEI_RECOVERING_FROM_RESET,
MEI_POWER_DOWN,
MEI_POWER_UP
enum mei_dev_state {
MEI_DEV_INITIALIZING = 0,
MEI_DEV_INIT_CLIENTS,
MEI_DEV_ENABLED,
MEI_DEV_RESETING,
MEI_DEV_DISABLED,
MEI_DEV_RECOVERING_FROM_RESET,
MEI_DEV_POWER_DOWN,
MEI_DEV_POWER_UP
};
const char *mei_dev_state_str(int state);
/* init clients states*/
enum mei_init_clients_states {
MEI_START_MESSAGE = 0,
@ -113,6 +122,12 @@ enum mei_file_transaction_states {
MEI_READ_COMPLETE
};
enum mei_wd_states {
MEI_WD_IDLE,
MEI_WD_RUNNING,
MEI_WD_STOPPING,
};
/* MEI CB */
enum mei_cb_major_types {
MEI_READ = 0,
@ -218,10 +233,9 @@ struct mei_device {
/*
* mei device states
*/
enum mei_states mei_state;
enum mei_dev_state dev_state;
enum mei_init_clients_states init_clients_state;
u16 init_clients_timer;
bool stop;
bool need_reset;
u32 extra_write_index;
@ -241,12 +255,11 @@ struct mei_device {
bool mei_host_buffer_is_empty;
struct mei_cl wd_cl;
enum mei_wd_states wd_state;
bool wd_interface_reg;
bool wd_pending;
bool wd_stopped;
bool wd_bypass; /* if false, don't refresh watchdog ME client */
u16 wd_timeout; /* seconds ((wd_data[1] << 8) + wd_data[0]) */
unsigned char wd_data[MEI_START_WD_DATA_SIZE];
u16 wd_timeout;
unsigned char wd_data[MEI_WD_START_MSG_SIZE];
struct file *iamthif_file_object;
@ -279,9 +292,10 @@ void mei_host_init_iamthif(struct mei_device *dev);
void mei_allocate_me_clients_storage(struct mei_device *dev);
u8 mei_find_me_client_update_filext(struct mei_device *dev,
struct mei_cl *priv,
const uuid_le *cguid, u8 client_id);
int mei_me_cl_update_filext(struct mei_device *dev, struct mei_cl *cl,
const uuid_le *cguid, u8 host_client_id);
int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid);
int mei_me_cl_by_id(struct mei_device *dev, u8 client_id);
/*
* MEI IO List Functions
@ -348,7 +362,6 @@ void mei_run_next_iamthif_cmd(struct mei_device *dev);
void mei_free_cb_private(struct mei_cl_cb *priv_cb);
int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid);
/*
* Register Access Function

View File

@ -48,8 +48,8 @@ const uuid_le mei_wd_guid = UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, 0x89,
static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout)
{
dev_dbg(&dev->pdev->dev, "wd: set timeout=%d.\n", timeout);
memcpy(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE);
memcpy(dev->wd_data + MEI_WD_PARAMS_SIZE, &timeout, sizeof(u16));
memcpy(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE);
memcpy(dev->wd_data + MEI_WD_HDR_SIZE, &timeout, sizeof(u16));
}
/**
@ -66,10 +66,11 @@ int mei_wd_host_init(struct mei_device *dev)
/* look for WD client and connect to it */
dev->wd_cl.state = MEI_FILE_DISCONNECTED;
dev->wd_timeout = AMT_WD_DEFAULT_TIMEOUT;
dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT;
dev->wd_state = MEI_WD_IDLE;
/* find ME WD client */
mei_find_me_client_update_filext(dev, &dev->wd_cl,
mei_me_cl_update_filext(dev, &dev->wd_cl,
&mei_wd_guid, MEI_WD_HOST_CLIENT_ID);
dev_dbg(&dev->pdev->dev, "wd: check client\n");
@ -108,10 +109,10 @@ int mei_wd_send(struct mei_device *dev)
mei_hdr->msg_complete = 1;
mei_hdr->reserved = 0;
if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE))
mei_hdr->length = MEI_START_WD_DATA_SIZE;
else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE))
mei_hdr->length = MEI_WD_PARAMS_SIZE;
if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE))
mei_hdr->length = MEI_WD_START_MSG_SIZE;
else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_HDR_SIZE))
mei_hdr->length = MEI_WD_STOP_MSG_SIZE;
else
return -EINVAL;
@ -128,18 +129,17 @@ int mei_wd_send(struct mei_device *dev)
* -EIO when message send fails
* -EINVAL when invalid message is to be sent
*/
int mei_wd_stop(struct mei_device *dev, bool preserve)
int mei_wd_stop(struct mei_device *dev)
{
int ret;
u16 wd_timeout = dev->wd_timeout;
cancel_delayed_work(&dev->timer_work);
if (dev->wd_cl.state != MEI_FILE_CONNECTED || !dev->wd_timeout)
if (dev->wd_cl.state != MEI_FILE_CONNECTED ||
dev->wd_state != MEI_WD_RUNNING)
return 0;
dev->wd_timeout = 0;
memcpy(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE);
dev->stop = true;
memcpy(dev->wd_data, mei_stop_wd_params, MEI_WD_STOP_MSG_SIZE);
dev->wd_state = MEI_WD_STOPPING;
ret = mei_flow_ctrl_creds(dev, &dev->wd_cl);
if (ret < 0)
@ -161,13 +161,14 @@ int mei_wd_stop(struct mei_device *dev, bool preserve)
} else {
dev->wd_pending = true;
}
dev->wd_stopped = false;
mutex_unlock(&dev->device_lock);
ret = wait_event_interruptible_timeout(dev->wait_stop_wd,
dev->wd_stopped, 10 * HZ);
dev->wd_state == MEI_WD_IDLE,
msecs_to_jiffies(MEI_WD_STOP_TIMEOUT));
mutex_lock(&dev->device_lock);
if (dev->wd_stopped) {
if (dev->wd_state == MEI_WD_IDLE) {
dev_dbg(&dev->pdev->dev, "wd: stop completed ret=%d.\n", ret);
ret = 0;
} else {
@ -177,9 +178,6 @@ int mei_wd_stop(struct mei_device *dev, bool preserve)
"wd: stop failed to complete ret=%d.\n", ret);
}
if (preserve)
dev->wd_timeout = wd_timeout;
out:
return ret;
}
@ -196,16 +194,16 @@ static int mei_wd_ops_start(struct watchdog_device *wd_dev)
int err = -ENODEV;
struct mei_device *dev;
dev = pci_get_drvdata(mei_device);
dev = watchdog_get_drvdata(wd_dev);
if (!dev)
return -ENODEV;
mutex_lock(&dev->device_lock);
if (dev->mei_state != MEI_ENABLED) {
if (dev->dev_state != MEI_DEV_ENABLED) {
dev_dbg(&dev->pdev->dev,
"wd: mei_state != MEI_ENABLED mei_state = %d\n",
dev->mei_state);
"wd: dev_state != MEI_DEV_ENABLED dev_state = %s\n",
mei_dev_state_str(dev->dev_state));
goto end_unlock;
}
@ -233,13 +231,13 @@ end_unlock:
static int mei_wd_ops_stop(struct watchdog_device *wd_dev)
{
struct mei_device *dev;
dev = pci_get_drvdata(mei_device);
dev = watchdog_get_drvdata(wd_dev);
if (!dev)
return -ENODEV;
mutex_lock(&dev->device_lock);
mei_wd_stop(dev, false);
mei_wd_stop(dev);
mutex_unlock(&dev->device_lock);
return 0;
@ -256,8 +254,8 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
{
int ret = 0;
struct mei_device *dev;
dev = pci_get_drvdata(mei_device);
dev = watchdog_get_drvdata(wd_dev);
if (!dev)
return -ENODEV;
@ -269,6 +267,8 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
goto end;
}
dev->wd_state = MEI_WD_RUNNING;
/* Check if we can send the ping to HW*/
if (dev->mei_host_buffer_is_empty &&
mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
@ -309,13 +309,13 @@ end:
static int mei_wd_ops_set_timeout(struct watchdog_device *wd_dev, unsigned int timeout)
{
struct mei_device *dev;
dev = pci_get_drvdata(mei_device);
dev = watchdog_get_drvdata(wd_dev);
if (!dev)
return -ENODEV;
/* Check Timeout value */
if (timeout < AMT_WD_MIN_TIMEOUT || timeout > AMT_WD_MAX_TIMEOUT)
if (timeout < MEI_WD_MIN_TIMEOUT || timeout > MEI_WD_MAX_TIMEOUT)
return -EINVAL;
mutex_lock(&dev->device_lock);
@ -341,37 +341,42 @@ static const struct watchdog_ops wd_ops = {
};
static const struct watchdog_info wd_info = {
.identity = INTEL_AMT_WATCHDOG_ID,
.options = WDIOF_KEEPALIVEPING | WDIOF_ALARMONLY,
.options = WDIOF_KEEPALIVEPING |
WDIOF_SETTIMEOUT |
WDIOF_ALARMONLY,
};
static struct watchdog_device amt_wd_dev = {
.info = &wd_info,
.ops = &wd_ops,
.timeout = AMT_WD_DEFAULT_TIMEOUT,
.min_timeout = AMT_WD_MIN_TIMEOUT,
.max_timeout = AMT_WD_MAX_TIMEOUT,
.timeout = MEI_WD_DEFAULT_TIMEOUT,
.min_timeout = MEI_WD_MIN_TIMEOUT,
.max_timeout = MEI_WD_MAX_TIMEOUT,
};
void mei_watchdog_register(struct mei_device *dev)
void mei_watchdog_register(struct mei_device *dev)
{
dev_dbg(&dev->pdev->dev, "dev->wd_timeout =%d.\n", dev->wd_timeout);
if (watchdog_register_device(&amt_wd_dev)) {
dev_err(&dev->pdev->dev,
"wd: unable to register watchdog device.\n");
dev->wd_interface_reg = false;
} else {
dev_dbg(&dev->pdev->dev,
"wd: successfully register watchdog interface.\n");
dev->wd_interface_reg = true;
return;
}
dev_dbg(&dev->pdev->dev,
"wd: successfully register watchdog interface.\n");
dev->wd_interface_reg = true;
watchdog_set_drvdata(&amt_wd_dev, dev);
}
void mei_watchdog_unregister(struct mei_device *dev)
{
if (dev->wd_interface_reg)
watchdog_unregister_device(&amt_wd_dev);
if (!dev->wd_interface_reg)
return;
watchdog_set_drvdata(&amt_wd_dev, NULL);
watchdog_unregister_device(&amt_wd_dev);
dev->wd_interface_reg = false;
}

View File

@ -699,7 +699,7 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
chip->pch_phub_base_address = pci_iomap(pdev, 1, 0);
if (chip->pch_phub_base_address == 0) {
if (chip->pch_phub_base_address == NULL) {
dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__);
ret = -ENOMEM;
goto err_pci_iomap;
@ -893,18 +893,7 @@ static struct pci_driver pch_phub_driver = {
.resume = pch_phub_resume
};
static int __init pch_phub_pci_init(void)
{
return pci_register_driver(&pch_phub_driver);
}
static void __exit pch_phub_pci_exit(void)
{
pci_unregister_driver(&pch_phub_driver);
}
module_init(pch_phub_pci_init);
module_exit(pch_phub_pci_exit);
module_pci_driver(pch_phub_driver);
MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7223) PHUB");
MODULE_LICENSE("GPL");

View File

@ -30,11 +30,13 @@
#include <linux/ti_wilink_st.h>
extern void st_kim_recv(void *, const unsigned char *, long);
void st_int_recv(void *, const unsigned char *, long);
/* function pointer pointing to either,
* st_kim_recv during registration to receive fw download responses
* st_int_recv after registration to receive proto stack responses
*/
void (*st_recv) (void*, const unsigned char*, long);
static void (*st_recv) (void *, const unsigned char *, long);
/********************************************************************/
static void add_channel_to_table(struct st_data_s *st_gdata,
@ -100,7 +102,7 @@ int st_int_write(struct st_data_s *st_gdata,
* push the skb received to relevant
* protocol stacks
*/
void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata)
static void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata)
{
pr_debug(" %s(prot:%d) ", __func__, chnl_id);
@ -140,7 +142,7 @@ void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata)
* This function is being called with spin lock held, protocol drivers are
* only expected to complete their waits and do nothing more than that.
*/
void st_reg_complete(struct st_data_s *st_gdata, char err)
static void st_reg_complete(struct st_data_s *st_gdata, char err)
{
unsigned char i = 0;
pr_info(" %s ", __func__);
@ -379,7 +381,7 @@ done:
* completely, return that skb which has the pending data.
* In normal cases, return top of txq.
*/
struct sk_buff *st_int_dequeue(struct st_data_s *st_gdata)
static struct sk_buff *st_int_dequeue(struct st_data_s *st_gdata)
{
struct sk_buff *returning_skb;
@ -401,7 +403,7 @@ struct sk_buff *st_int_dequeue(struct st_data_s *st_gdata)
* txq and waitq needs protection since the other contexts
* may be sending data, waking up chip.
*/
void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb)
static void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb)
{
unsigned long flags = 0;

View File

@ -63,10 +63,27 @@ static struct platform_device *st_get_plat_device(int id)
* in case of error don't complete so that waiting for proper
* response times out
*/
void validate_firmware_response(struct kim_data_s *kim_gdata)
static void validate_firmware_response(struct kim_data_s *kim_gdata)
{
struct sk_buff *skb = kim_gdata->rx_skb;
if (unlikely(skb->data[5] != 0)) {
if (!skb)
return;
/* these magic numbers are the position in the response buffer which
* allows us to distinguish whether the response is for the read
* version info. command
*/
if (skb->data[2] == 0x01 && skb->data[3] == 0x01 &&
skb->data[4] == 0x10 && skb->data[5] == 0x00) {
/* fw version response */
memcpy(kim_gdata->resp_buffer,
kim_gdata->rx_skb->data,
kim_gdata->rx_skb->len);
complete_all(&kim_gdata->kim_rcvd);
kim_gdata->rx_state = ST_W4_PACKET_TYPE;
kim_gdata->rx_skb = NULL;
kim_gdata->rx_count = 0;
} else if (unlikely(skb->data[5] != 0)) {
pr_err("no proper response during fw download");
pr_err("data6 %x", skb->data[5]);
kfree_skb(skb);
@ -119,7 +136,7 @@ static inline int kim_check_data_len(struct kim_data_s *kim_gdata, int len)
* have been observed to come in bursts of different
* tty_receive and hence the logic
*/
void kim_int_recv(struct kim_data_s *kim_gdata,
static void kim_int_recv(struct kim_data_s *kim_gdata,
const unsigned char *data, long count)
{
const unsigned char *ptr;
@ -207,16 +224,19 @@ static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name)
return -EIO;
}
if (!wait_for_completion_timeout
(&kim_gdata->kim_rcvd, msecs_to_jiffies(CMD_RESP_TIME))) {
if (!wait_for_completion_interruptible_timeout(
&kim_gdata->kim_rcvd, msecs_to_jiffies(CMD_RESP_TIME))) {
pr_err(" waiting for ver info- timed out ");
return -ETIMEDOUT;
}
INIT_COMPLETION(kim_gdata->kim_rcvd);
/* the positions 12 & 13 in the response buffer provide with the
* chip, major & minor numbers
*/
version =
MAKEWORD(kim_gdata->resp_buffer[13],
kim_gdata->resp_buffer[14]);
MAKEWORD(kim_gdata->resp_buffer[12],
kim_gdata->resp_buffer[13]);
chip = (version & 0x7C00) >> 10;
min_ver = (version & 0x007F);
maj_ver = (version & 0x0380) >> 7;
@ -236,7 +256,7 @@ static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name)
return 0;
}
void skip_change_remote_baud(unsigned char **ptr, long *len)
static void skip_change_remote_baud(unsigned char **ptr, long *len)
{
unsigned char *nxt_action, *cur_action;
cur_action = *ptr;
@ -370,9 +390,9 @@ static long download_firmware(struct kim_data_s *kim_gdata)
break;
case ACTION_WAIT_EVENT: /* wait */
pr_debug("W");
if (!wait_for_completion_timeout
(&kim_gdata->kim_rcvd,
msecs_to_jiffies(CMD_RESP_TIME))) {
if (!wait_for_completion_interruptible_timeout(
&kim_gdata->kim_rcvd,
msecs_to_jiffies(CMD_RESP_TIME))) {
pr_err("response timeout during fw download ");
/* timed out */
release_firmware(kim_gdata->fw_entry);
@ -410,16 +430,10 @@ void st_kim_recv(void *disc_data, const unsigned char *data, long count)
struct st_data_s *st_gdata = (struct st_data_s *)disc_data;
struct kim_data_s *kim_gdata = st_gdata->kim_data;
/* copy to local buffer */
if (unlikely(data[4] == 0x01 && data[5] == 0x10 && data[0] == 0x04)) {
/* must be the read_ver_cmd */
memcpy(kim_gdata->resp_buffer, data, count);
complete_all(&kim_gdata->kim_rcvd);
return;
} else {
kim_int_recv(kim_gdata, data, count);
/* either completes or times out */
}
/* proceed to gather all data and distinguish read fw version response
* from other fw responses when data gathering is complete
*/
kim_int_recv(kim_gdata, data, count);
return;
}
@ -454,11 +468,6 @@ long st_kim_start(void *kim_data)
if (pdata->chip_enable)
pdata->chip_enable(kim_gdata);
/* Configure BT nShutdown to HIGH state */
gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
mdelay(5); /* FIXME: a proper toggle */
gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH);
mdelay(100);
/* re-initialize the completion */
INIT_COMPLETION(kim_gdata->ldisc_installed);
/* send notification to UIM */
@ -467,8 +476,8 @@ long st_kim_start(void *kim_data)
sysfs_notify(&kim_gdata->kim_pdev->dev.kobj,
NULL, "install");
/* wait for ldisc to be installed */
err = wait_for_completion_timeout(&kim_gdata->ldisc_installed,
msecs_to_jiffies(LDISC_TIME));
err = wait_for_completion_interruptible_timeout(
&kim_gdata->ldisc_installed, msecs_to_jiffies(LDISC_TIME));
if (!err) {
/* ldisc installation timeout,
* flush uart, power cycle BT_EN */
@ -500,8 +509,7 @@ long st_kim_start(void *kim_data)
* (b) upon failure to either install ldisc or download firmware.
* The function is responsible to (a) notify UIM about un-installation,
* (b) flush UART if the ldisc was installed.
* (c) reset BT_EN - pull down nshutdown at the end.
* (d) invoke platform's chip disabling routine.
* (c) invoke platform's chip disabling routine.
*/
long st_kim_stop(void *kim_data)
{
@ -526,20 +534,13 @@ long st_kim_stop(void *kim_data)
sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, NULL, "install");
/* wait for ldisc to be un-installed */
err = wait_for_completion_timeout(&kim_gdata->ldisc_installed,
msecs_to_jiffies(LDISC_TIME));
err = wait_for_completion_interruptible_timeout(
&kim_gdata->ldisc_installed, msecs_to_jiffies(LDISC_TIME));
if (!err) { /* timeout */
pr_err(" timed out waiting for ldisc to be un-installed");
return -ETIMEDOUT;
err = -ETIMEDOUT;
}
/* By default configure BT nShutdown to LOW state */
gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
mdelay(1);
gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH);
mdelay(1);
gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
/* platform specific disable */
if (pdata->chip_disable)
pdata->chip_disable(kim_gdata);
@ -701,7 +702,7 @@ static const struct file_operations list_debugfs_fops = {
* board-*.c file
*/
struct dentry *kim_debugfs_dir;
static struct dentry *kim_debugfs_dir;
static int kim_probe(struct platform_device *pdev)
{
long status;
@ -731,20 +732,6 @@ static int kim_probe(struct platform_device *pdev)
/* refer to itself */
kim_gdata->core_data->kim_data = kim_gdata;
/* Claim the chip enable nShutdown gpio from the system */
kim_gdata->nshutdown = pdata->nshutdown_gpio;
status = gpio_request(kim_gdata->nshutdown, "kim");
if (unlikely(status)) {
pr_err(" gpio %ld request failed ", kim_gdata->nshutdown);
return status;
}
/* Configure nShutdown GPIO as output=0 */
status = gpio_direction_output(kim_gdata->nshutdown, 0);
if (unlikely(status)) {
pr_err(" unable to configure gpio %ld", kim_gdata->nshutdown);
return status;
}
/* get reference of pdev for request_firmware
*/
kim_gdata->kim_pdev = pdev;
@ -780,18 +767,10 @@ static int kim_probe(struct platform_device *pdev)
static int kim_remove(struct platform_device *pdev)
{
/* free the GPIOs requested */
struct ti_st_plat_data *pdata = pdev->dev.platform_data;
struct kim_data_s *kim_gdata;
kim_gdata = dev_get_drvdata(&pdev->dev);
/* Free the Bluetooth/FM/GPIO
* nShutdown gpio from the system
*/
gpio_free(pdata->nshutdown_gpio);
pr_info("nshutdown GPIO Freed");
debugfs_remove_recursive(kim_debugfs_dir);
sysfs_remove_group(&pdev->dev.kobj, &uim_attr_grp);
pr_info("sysfs entries removed");
@ -804,7 +783,7 @@ static int kim_remove(struct platform_device *pdev)
return 0;
}
int kim_suspend(struct platform_device *pdev, pm_message_t state)
static int kim_suspend(struct platform_device *pdev, pm_message_t state)
{
struct ti_st_plat_data *pdata = pdev->dev.platform_data;
@ -814,7 +793,7 @@ int kim_suspend(struct platform_device *pdev, pm_message_t state)
return -EOPNOTSUPP;
}
int kim_resume(struct platform_device *pdev)
static int kim_resume(struct platform_device *pdev)
{
struct ti_st_plat_data *pdata = pdev->dev.platform_data;

View File

@ -60,7 +60,6 @@ config W1_MASTER_GPIO
config HDQ_MASTER_OMAP
tristate "OMAP HDQ driver"
depends on ARCH_OMAP2PLUS
help
Say Y here if you want support for the 1-wire or HDQ Interface
on an OMAP processor.

View File

@ -18,9 +18,6 @@
#include <linux/sched.h>
#include <linux/pm_runtime.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include "../w1.h"
#include "../w1_int.h"
@ -73,11 +70,11 @@ struct hdq_data {
};
static int __devinit omap_hdq_probe(struct platform_device *pdev);
static int omap_hdq_remove(struct platform_device *pdev);
static int __devexit omap_hdq_remove(struct platform_device *pdev);
static struct platform_driver omap_hdq_driver = {
.probe = omap_hdq_probe,
.remove = omap_hdq_remove,
.remove = __devexit_p(omap_hdq_remove),
.driver = {
.name = "omap_hdq",
},
@ -538,39 +535,35 @@ static void omap_w1_write_byte(void *_hdq, u8 byte)
hdq_data->init_trans = 0;
mutex_unlock(&hdq_data->hdq_mutex);
}
return;
}
static int __devinit omap_hdq_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct hdq_data *hdq_data;
struct resource *res;
int ret, irq;
u8 rev;
hdq_data = kmalloc(sizeof(*hdq_data), GFP_KERNEL);
hdq_data = devm_kzalloc(dev, sizeof(*hdq_data), GFP_KERNEL);
if (!hdq_data) {
dev_dbg(&pdev->dev, "unable to allocate memory\n");
ret = -ENOMEM;
goto err_kmalloc;
return -ENOMEM;
}
hdq_data->dev = &pdev->dev;
hdq_data->dev = dev;
platform_set_drvdata(pdev, hdq_data);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_dbg(&pdev->dev, "unable to get resource\n");
ret = -ENXIO;
goto err_resource;
return -ENXIO;
}
hdq_data->hdq_base = ioremap(res->start, SZ_4K);
hdq_data->hdq_base = devm_request_and_ioremap(dev, res);
if (!hdq_data->hdq_base) {
dev_dbg(&pdev->dev, "ioremap failed\n");
ret = -EINVAL;
goto err_ioremap;
return -ENOMEM;
}
hdq_data->hdq_usecount = 0;
@ -591,7 +584,8 @@ static int __devinit omap_hdq_probe(struct platform_device *pdev)
goto err_irq;
}
ret = request_irq(irq, hdq_isr, IRQF_DISABLED, "omap_hdq", hdq_data);
ret = devm_request_irq(dev, irq, hdq_isr, IRQF_DISABLED,
"omap_hdq", hdq_data);
if (ret < 0) {
dev_dbg(&pdev->dev, "could not request irq\n");
goto err_irq;
@ -616,19 +610,10 @@ err_irq:
err_w1:
pm_runtime_disable(&pdev->dev);
iounmap(hdq_data->hdq_base);
err_ioremap:
err_resource:
platform_set_drvdata(pdev, NULL);
kfree(hdq_data);
err_kmalloc:
return ret;
}
static int omap_hdq_remove(struct platform_device *pdev)
static int __devexit omap_hdq_remove(struct platform_device *pdev)
{
struct hdq_data *hdq_data = platform_get_drvdata(pdev);
@ -644,27 +629,11 @@ static int omap_hdq_remove(struct platform_device *pdev)
/* remove module dependency */
pm_runtime_disable(&pdev->dev);
free_irq(INT_24XX_HDQ_IRQ, hdq_data);
platform_set_drvdata(pdev, NULL);
iounmap(hdq_data->hdq_base);
kfree(hdq_data);
return 0;
}
static int __init
omap_hdq_init(void)
{
return platform_driver_register(&omap_hdq_driver);
}
module_init(omap_hdq_init);
static void __exit
omap_hdq_exit(void)
{
platform_driver_unregister(&omap_hdq_driver);
}
module_exit(omap_hdq_exit);
module_platform_driver(omap_hdq_driver);
module_param(w1_id, int, S_IRUSR);
MODULE_PARM_DESC(w1_id, "1-wire id for the slave detection");

View File

@ -14,6 +14,8 @@
#include <linux/slab.h>
#include <linux/w1-gpio.h>
#include <linux/gpio.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include "../w1.h"
#include "../w1_int.h"
@ -42,12 +44,55 @@ static u8 w1_gpio_read_bit(void *data)
return gpio_get_value(pdata->pin) ? 1 : 0;
}
#ifdef CONFIG_OF
static struct of_device_id w1_gpio_dt_ids[] = {
{ .compatible = "w1-gpio" },
{}
};
MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids);
static int w1_gpio_probe_dt(struct platform_device *pdev)
{
struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
struct device_node *np = pdev->dev.of_node;
const struct of_device_id *of_id =
of_match_device(w1_gpio_dt_ids, &pdev->dev);
if (!of_id)
return 0;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
if (of_get_property(np, "linux,open-drain", NULL))
pdata->is_open_drain = 1;
pdata->pin = of_get_gpio(np, 0);
pdata->ext_pullup_enable_pin = of_get_gpio(np, 1);
pdev->dev.platform_data = pdata;
return 0;
}
#else
static int w1_gpio_probe_dt(struct platform_device *pdev)
{
return 0;
}
#endif
static int __init w1_gpio_probe(struct platform_device *pdev)
{
struct w1_bus_master *master;
struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
struct w1_gpio_platform_data *pdata;
int err;
err = w1_gpio_probe_dt(pdev);
if (err < 0)
return err;
pdata = pdev->dev.platform_data;
if (!pdata)
return -ENXIO;
@ -59,6 +104,13 @@ static int __init w1_gpio_probe(struct platform_device *pdev)
if (err)
goto free_master;
if (gpio_is_valid(pdata->ext_pullup_enable_pin)) {
err = gpio_request_one(pdata->ext_pullup_enable_pin,
GPIOF_INIT_LOW, "w1 pullup");
if (err < 0)
goto free_gpio;
}
master->data = pdata;
master->read_bit = w1_gpio_read_bit;
@ -72,15 +124,21 @@ static int __init w1_gpio_probe(struct platform_device *pdev)
err = w1_add_master_device(master);
if (err)
goto free_gpio;
goto free_gpio_ext_pu;
if (pdata->enable_external_pullup)
pdata->enable_external_pullup(1);
if (gpio_is_valid(pdata->ext_pullup_enable_pin))
gpio_set_value(pdata->ext_pullup_enable_pin, 1);
platform_set_drvdata(pdev, master);
return 0;
free_gpio_ext_pu:
if (gpio_is_valid(pdata->ext_pullup_enable_pin))
gpio_free(pdata->ext_pullup_enable_pin);
free_gpio:
gpio_free(pdata->pin);
free_master:
@ -97,6 +155,9 @@ static int __exit w1_gpio_remove(struct platform_device *pdev)
if (pdata->enable_external_pullup)
pdata->enable_external_pullup(0);
if (gpio_is_valid(pdata->ext_pullup_enable_pin))
gpio_set_value(pdata->ext_pullup_enable_pin, 0);
w1_remove_master_device(master);
gpio_free(pdata->pin);
kfree(master);
@ -135,6 +196,7 @@ static struct platform_driver w1_gpio_driver = {
.driver = {
.name = "w1-gpio",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(w1_gpio_dt_ids),
},
.remove = __exit_p(w1_gpio_remove),
.suspend = w1_gpio_suspend,

View File

@ -281,9 +281,10 @@ struct kim_data_s {
long st_kim_start(void *);
long st_kim_stop(void *);
void st_kim_recv(void *, const unsigned char *, long count);
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

View File

@ -19,6 +19,7 @@ struct w1_gpio_platform_data {
unsigned int pin;
unsigned int is_open_drain:1;
void (*enable_external_pullup)(int enable);
unsigned int ext_pullup_enable_pin;
};
#endif /* _LINUX_W1_GPIO_H */