From 0ccc7955acc19e7f4515e51993b7b95cf5a35fdc Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 30 Jul 2014 15:39:02 +0900 Subject: extcon: sm5502: Fix bug to check cable type This patch fix bug when checking cable type. SM5502 have to use ADC value to get correct cable type. Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-sm5502.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c index 560d7dccec7b..a1ba9242e9cb 100644 --- a/drivers/extcon/extcon-sm5502.c +++ b/drivers/extcon/extcon-sm5502.c @@ -300,7 +300,7 @@ static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info) * If ADC is SM5502_MUIC_ADC_GROUND(0x0), external cable hasn't * connected with to MUIC device. */ - cable_type &= SM5502_REG_ADC_MASK; + cable_type = adc & SM5502_REG_ADC_MASK; if (cable_type == SM5502_MUIC_ADC_GROUND) return SM5502_MUIC_ADC_GROUND; -- cgit v1.2.3 From 0746d5d31f61721bf3e4ab84d75fac08d03e2a9a Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 12 Aug 2014 13:28:11 +0900 Subject: extcon: sm5502: Add I2C dependency to fix build break This patch add I2C configuration dependency to fix following build break. If specific kernel build I2C as module, extcon-sm5502 have to depend on I2C configuration. drivers/built-in.o: In function `regmap_smbus_byte_reg_read': regmap-i2c.c:(.text+0x5030a): undefined reference to `i2c_smbus_read_byte_data' drivers/built-in.o: In function `regmap_smbus_byte_reg_write': regmap-i2c.c:(.text+0x50338): undefined reference to `i2c_smbus_write_byte_data' drivers/built-in.o: In function `regmap_smbus_word_reg_read': regmap-i2c.c:(.text+0x50356): undefined reference to `i2c_smbus_read_word_data' drivers/built-in.o: In function `regmap_smbus_word_reg_write': regmap-i2c.c:(.text+0x50384): undefined reference to `i2c_smbus_write_word_data' drivers/built-in.o: In function `regmap_i2c_read': regmap-i2c.c:(.text+0x503cf): undefined reference to `i2c_transfer' drivers/built-in.o: In function `regmap_i2c_gather_write': regmap-i2c.c:(.text+0x50442): undefined reference to `i2c_transfer' drivers/built-in.o: In function `regmap_i2c_write': regmap-i2c.c:(.text+0x50474): undefined reference to `i2c_master_send' drivers/built-in.o: In function `sm5502_muic_i2c_init': extcon-sm5502.c:(.init.text+0x6630): undefined reference to `i2c_register_driver' Signed-off-by: Chanwoo Choi --- drivers/extcon/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index 6f2f4727de2c..764f3a113e0a 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig @@ -72,6 +72,7 @@ config EXTCON_PALMAS config EXTCON_SM5502 tristate "SM5502 EXTCON support" + depends on I2C select IRQ_DOMAIN select REGMAP_I2C select REGMAP_IRQ -- cgit v1.2.3 From ca2a07e45d1d3d31a0a85d2f63d81a897c610040 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Thu, 31 Jul 2014 16:32:46 +0900 Subject: extcon: sm5502: Move sm5502.h header file to extcon directory This patch move sm5502.h header file from 'include/linux/extcon' to 'driver/extcon' because sm5502.h is used for driver/extcon/extcon-sm5502.c. and remove duplicate license description. Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-sm5502.c | 8 +- drivers/extcon/extcon-sm5502.h | 282 ++++++++++++++++++++++++++++++++++++++++ include/linux/extcon/sm5502.h | 287 ----------------------------------------- 3 files changed, 284 insertions(+), 293 deletions(-) create mode 100644 drivers/extcon/extcon-sm5502.h delete mode 100644 include/linux/extcon/sm5502.h diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c index a1ba9242e9cb..f94d66aae9e3 100644 --- a/drivers/extcon/extcon-sm5502.c +++ b/drivers/extcon/extcon-sm5502.c @@ -8,11 +8,6 @@ * 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. See the - * GNU General Public License for more details. */ #include @@ -26,7 +21,8 @@ #include #include #include -#include + +#include "extcon-sm5502.h" #define DELAY_MS_DEFAULT 17000 /* unit: millisecond */ diff --git a/drivers/extcon/extcon-sm5502.h b/drivers/extcon/extcon-sm5502.h new file mode 100644 index 000000000000..974b53222f56 --- /dev/null +++ b/drivers/extcon/extcon-sm5502.h @@ -0,0 +1,282 @@ +/* + * sm5502.h + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd + * + * 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. + */ + +#ifndef __LINUX_EXTCON_SM5502_H +#define __LINUX_EXTCON_SM5502_H + +enum sm5502_types { + TYPE_SM5502, +}; + +/* SM5502 registers */ +enum sm5502_reg { + SM5502_REG_DEVICE_ID = 0x01, + SM5502_REG_CONTROL, + SM5502_REG_INT1, + SM5502_REG_INT2, + SM5502_REG_INTMASK1, + SM5502_REG_INTMASK2, + SM5502_REG_ADC, + SM5502_REG_TIMING_SET1, + SM5502_REG_TIMING_SET2, + SM5502_REG_DEV_TYPE1, + SM5502_REG_DEV_TYPE2, + SM5502_REG_BUTTON1, + SM5502_REG_BUTTON2, + SM5502_REG_CAR_KIT_STATUS, + SM5502_REG_RSVD1, + SM5502_REG_RSVD2, + SM5502_REG_RSVD3, + SM5502_REG_RSVD4, + SM5502_REG_MANUAL_SW1, + SM5502_REG_MANUAL_SW2, + SM5502_REG_DEV_TYPE3, + SM5502_REG_RSVD5, + SM5502_REG_RSVD6, + SM5502_REG_RSVD7, + SM5502_REG_RSVD8, + SM5502_REG_RSVD9, + SM5502_REG_RESET, + SM5502_REG_RSVD10, + SM5502_REG_RESERVED_ID1, + SM5502_REG_RSVD11, + SM5502_REG_RSVD12, + SM5502_REG_RESERVED_ID2, + SM5502_REG_RSVD13, + SM5502_REG_OCP, + SM5502_REG_RSVD14, + SM5502_REG_RSVD15, + SM5502_REG_RSVD16, + SM5502_REG_RSVD17, + SM5502_REG_RSVD18, + SM5502_REG_RSVD19, + SM5502_REG_RSVD20, + SM5502_REG_RSVD21, + SM5502_REG_RSVD22, + SM5502_REG_RSVD23, + SM5502_REG_RSVD24, + SM5502_REG_RSVD25, + SM5502_REG_RSVD26, + SM5502_REG_RSVD27, + SM5502_REG_RSVD28, + SM5502_REG_RSVD29, + SM5502_REG_RSVD30, + SM5502_REG_RSVD31, + SM5502_REG_RSVD32, + SM5502_REG_RSVD33, + SM5502_REG_RSVD34, + SM5502_REG_RSVD35, + SM5502_REG_RSVD36, + SM5502_REG_RESERVED_ID3, + + SM5502_REG_END, +}; + +/* Define SM5502 MASK/SHIFT constant */ +#define SM5502_REG_DEVICE_ID_VENDOR_SHIFT 0 +#define SM5502_REG_DEVICE_ID_VERSION_SHIFT 3 +#define SM5502_REG_DEVICE_ID_VENDOR_MASK (0x3 << SM5502_REG_DEVICE_ID_VENDOR_SHIFT) +#define SM5502_REG_DEVICE_ID_VERSION_MASK (0x1f << SM5502_REG_DEVICE_ID_VERSION_SHIFT) + +#define SM5502_REG_CONTROL_MASK_INT_SHIFT 0 +#define SM5502_REG_CONTROL_WAIT_SHIFT 1 +#define SM5502_REG_CONTROL_MANUAL_SW_SHIFT 2 +#define SM5502_REG_CONTROL_RAW_DATA_SHIFT 3 +#define SM5502_REG_CONTROL_SW_OPEN_SHIFT 4 +#define SM5502_REG_CONTROL_MASK_INT_MASK (0x1 << SM5502_REG_CONTROL_MASK_INT_SHIFT) +#define SM5502_REG_CONTROL_WAIT_MASK (0x1 << SM5502_REG_CONTROL_WAIT_SHIFT) +#define SM5502_REG_CONTROL_MANUAL_SW_MASK (0x1 << SM5502_REG_CONTROL_MANUAL_SW_SHIFT) +#define SM5502_REG_CONTROL_RAW_DATA_MASK (0x1 << SM5502_REG_CONTROL_RAW_DATA_SHIFT) +#define SM5502_REG_CONTROL_SW_OPEN_MASK (0x1 << SM5502_REG_CONTROL_SW_OPEN_SHIFT) + +#define SM5502_REG_INTM1_ATTACH_SHIFT 0 +#define SM5502_REG_INTM1_DETACH_SHIFT 1 +#define SM5502_REG_INTM1_KP_SHIFT 2 +#define SM5502_REG_INTM1_LKP_SHIFT 3 +#define SM5502_REG_INTM1_LKR_SHIFT 4 +#define SM5502_REG_INTM1_OVP_EVENT_SHIFT 5 +#define SM5502_REG_INTM1_OCP_EVENT_SHIFT 6 +#define SM5502_REG_INTM1_OVP_OCP_DIS_SHIFT 7 +#define SM5502_REG_INTM1_ATTACH_MASK (0x1 << SM5502_REG_INTM1_ATTACH_SHIFT) +#define SM5502_REG_INTM1_DETACH_MASK (0x1 << SM5502_REG_INTM1_DETACH_SHIFT) +#define SM5502_REG_INTM1_KP_MASK (0x1 << SM5502_REG_INTM1_KP_SHIFT) +#define SM5502_REG_INTM1_LKP_MASK (0x1 << SM5502_REG_INTM1_LKP_SHIFT) +#define SM5502_REG_INTM1_LKR_MASK (0x1 << SM5502_REG_INTM1_LKR_SHIFT) +#define SM5502_REG_INTM1_OVP_EVENT_MASK (0x1 << SM5502_REG_INTM1_OVP_EVENT_SHIFT) +#define SM5502_REG_INTM1_OCP_EVENT_MASK (0x1 << SM5502_REG_INTM1_OCP_EVENT_SHIFT) +#define SM5502_REG_INTM1_OVP_OCP_DIS_MASK (0x1 << SM5502_REG_INTM1_OVP_OCP_DIS_SHIFT) + +#define SM5502_REG_INTM2_VBUS_DET_SHIFT 0 +#define SM5502_REG_INTM2_REV_ACCE_SHIFT 1 +#define SM5502_REG_INTM2_ADC_CHG_SHIFT 2 +#define SM5502_REG_INTM2_STUCK_KEY_SHIFT 3 +#define SM5502_REG_INTM2_STUCK_KEY_RCV_SHIFT 4 +#define SM5502_REG_INTM2_MHL_SHIFT 5 +#define SM5502_REG_INTM2_VBUS_DET_MASK (0x1 << SM5502_REG_INTM2_VBUS_DET_SHIFT) +#define SM5502_REG_INTM2_REV_ACCE_MASK (0x1 << SM5502_REG_INTM2_REV_ACCE_SHIFT) +#define SM5502_REG_INTM2_ADC_CHG_MASK (0x1 << SM5502_REG_INTM2_ADC_CHG_SHIFT) +#define SM5502_REG_INTM2_STUCK_KEY_MASK (0x1 << SM5502_REG_INTM2_STUCK_KEY_SHIFT) +#define SM5502_REG_INTM2_STUCK_KEY_RCV_MASK (0x1 << SM5502_REG_INTM2_STUCK_KEY_RCV_SHIFT) +#define SM5502_REG_INTM2_MHL_MASK (0x1 << SM5502_REG_INTM2_MHL_SHIFT) + +#define SM5502_REG_ADC_SHIFT 0 +#define SM5502_REG_ADC_MASK (0x1f << SM5502_REG_ADC_SHIFT) + +#define SM5502_REG_TIMING_SET1_KEY_PRESS_SHIFT 4 +#define SM5502_REG_TIMING_SET1_KEY_PRESS_MASK (0xf << SM5502_REG_TIMING_SET1_KEY_PRESS_SHIFT) +#define TIMING_KEY_PRESS_100MS 0x0 +#define TIMING_KEY_PRESS_200MS 0x1 +#define TIMING_KEY_PRESS_300MS 0x2 +#define TIMING_KEY_PRESS_400MS 0x3 +#define TIMING_KEY_PRESS_500MS 0x4 +#define TIMING_KEY_PRESS_600MS 0x5 +#define TIMING_KEY_PRESS_700MS 0x6 +#define TIMING_KEY_PRESS_800MS 0x7 +#define TIMING_KEY_PRESS_900MS 0x8 +#define TIMING_KEY_PRESS_1000MS 0x9 +#define SM5502_REG_TIMING_SET1_ADC_DET_SHIFT 0 +#define SM5502_REG_TIMING_SET1_ADC_DET_MASK (0xf << SM5502_REG_TIMING_SET1_ADC_DET_SHIFT) +#define TIMING_ADC_DET_50MS 0x0 +#define TIMING_ADC_DET_100MS 0x1 +#define TIMING_ADC_DET_150MS 0x2 +#define TIMING_ADC_DET_200MS 0x3 +#define TIMING_ADC_DET_300MS 0x4 +#define TIMING_ADC_DET_400MS 0x5 +#define TIMING_ADC_DET_500MS 0x6 +#define TIMING_ADC_DET_600MS 0x7 +#define TIMING_ADC_DET_700MS 0x8 +#define TIMING_ADC_DET_800MS 0x9 +#define TIMING_ADC_DET_900MS 0xA +#define TIMING_ADC_DET_1000MS 0xB + +#define SM5502_REG_TIMING_SET2_SW_WAIT_SHIFT 4 +#define SM5502_REG_TIMING_SET2_SW_WAIT_MASK (0xf << SM5502_REG_TIMING_SET2_SW_WAIT_SHIFT) +#define TIMING_SW_WAIT_10MS 0x0 +#define TIMING_SW_WAIT_30MS 0x1 +#define TIMING_SW_WAIT_50MS 0x2 +#define TIMING_SW_WAIT_70MS 0x3 +#define TIMING_SW_WAIT_90MS 0x4 +#define TIMING_SW_WAIT_110MS 0x5 +#define TIMING_SW_WAIT_130MS 0x6 +#define TIMING_SW_WAIT_150MS 0x7 +#define TIMING_SW_WAIT_170MS 0x8 +#define TIMING_SW_WAIT_190MS 0x9 +#define TIMING_SW_WAIT_210MS 0xA +#define SM5502_REG_TIMING_SET2_LONG_KEY_SHIFT 0 +#define SM5502_REG_TIMING_SET2_LONG_KEY_MASK (0xf << SM5502_REG_TIMING_SET2_LONG_KEY_SHIFT) +#define TIMING_LONG_KEY_300MS 0x0 +#define TIMING_LONG_KEY_400MS 0x1 +#define TIMING_LONG_KEY_500MS 0x2 +#define TIMING_LONG_KEY_600MS 0x3 +#define TIMING_LONG_KEY_700MS 0x4 +#define TIMING_LONG_KEY_800MS 0x5 +#define TIMING_LONG_KEY_900MS 0x6 +#define TIMING_LONG_KEY_1000MS 0x7 +#define TIMING_LONG_KEY_1100MS 0x8 +#define TIMING_LONG_KEY_1200MS 0x9 +#define TIMING_LONG_KEY_1300MS 0xA +#define TIMING_LONG_KEY_1400MS 0xB +#define TIMING_LONG_KEY_1500MS 0xC + +#define SM5502_REG_DEV_TYPE1_AUDIO_TYPE1_SHIFT 0 +#define SM5502_REG_DEV_TYPE1_AUDIO_TYPE2_SHIFT 1 +#define SM5502_REG_DEV_TYPE1_USB_SDP_SHIFT 2 +#define SM5502_REG_DEV_TYPE1_UART_SHIFT 3 +#define SM5502_REG_DEV_TYPE1_CAR_KIT_CHARGER_SHIFT 4 +#define SM5502_REG_DEV_TYPE1_USB_CHG_SHIFT 5 +#define SM5502_REG_DEV_TYPE1_DEDICATED_CHG_SHIFT 6 +#define SM5502_REG_DEV_TYPE1_USB_OTG_SHIFT 7 +#define SM5502_REG_DEV_TYPE1_AUDIO_TYPE1_MASK (0x1 << SM5502_REG_DEV_TYPE1_AUDIO_TYPE1_SHIFT) +#define SM5502_REG_DEV_TYPE1_AUDIO_TYPE1__MASK (0x1 << SM5502_REG_DEV_TYPE1_AUDIO_TYPE2_SHIFT) +#define SM5502_REG_DEV_TYPE1_USB_SDP_MASK (0x1 << SM5502_REG_DEV_TYPE1_USB_SDP_SHIFT) +#define SM5502_REG_DEV_TYPE1_UART_MASK (0x1 << SM5502_REG_DEV_TYPE1_UART_SHIFT) +#define SM5502_REG_DEV_TYPE1_CAR_KIT_CHARGER_MASK (0x1 << SM5502_REG_DEV_TYPE1_CAR_KIT_CHARGER_SHIFT) +#define SM5502_REG_DEV_TYPE1_USB_CHG_MASK (0x1 << SM5502_REG_DEV_TYPE1_USB_CHG_SHIFT) +#define SM5502_REG_DEV_TYPE1_DEDICATED_CHG_MASK (0x1 << SM5502_REG_DEV_TYPE1_DEDICATED_CHG_SHIFT) +#define SM5502_REG_DEV_TYPE1_USB_OTG_MASK (0x1 << SM5502_REG_DEV_TYPE1_USB_OTG_SHIFT) + +#define SM5502_REG_DEV_TYPE2_JIG_USB_ON_SHIFT 0 +#define SM5502_REG_DEV_TYPE2_JIG_USB_OFF_SHIFT 1 +#define SM5502_REG_DEV_TYPE2_JIG_UART_ON_SHIFT 2 +#define SM5502_REG_DEV_TYPE2_JIG_UART_OFF_SHIFT 3 +#define SM5502_REG_DEV_TYPE2_PPD_SHIFT 4 +#define SM5502_REG_DEV_TYPE2_TTY_SHIFT 5 +#define SM5502_REG_DEV_TYPE2_AV_CABLE_SHIFT 6 +#define SM5502_REG_DEV_TYPE2_JIG_USB_ON_MASK (0x1 << SM5502_REG_DEV_TYPE2_JIG_USB_ON_SHIFT) +#define SM5502_REG_DEV_TYPE2_JIG_USB_OFF_MASK (0x1 << SM5502_REG_DEV_TYPE2_JIG_USB_OFF_SHIFT) +#define SM5502_REG_DEV_TYPE2_JIG_UART_ON_MASK (0x1 << SM5502_REG_DEV_TYPE2_JIG_UART_ON_SHIFT) +#define SM5502_REG_DEV_TYPE2_JIG_UART_OFF_MASK (0x1 << SM5502_REG_DEV_TYPE2_JIG_UART_OFF_SHIFT) +#define SM5502_REG_DEV_TYPE2_PPD_MASK (0x1 << SM5502_REG_DEV_TYPE2_PPD_SHIFT) +#define SM5502_REG_DEV_TYPE2_TTY_MASK (0x1 << SM5502_REG_DEV_TYPE2_TTY_SHIFT) +#define SM5502_REG_DEV_TYPE2_AV_CABLE_MASK (0x1 << SM5502_REG_DEV_TYPE2_AV_CABLE_SHIFT) + +#define SM5502_REG_MANUAL_SW1_VBUSIN_SHIFT 0 +#define SM5502_REG_MANUAL_SW1_DP_SHIFT 2 +#define SM5502_REG_MANUAL_SW1_DM_SHIFT 5 +#define SM5502_REG_MANUAL_SW1_VBUSIN_MASK (0x3 << SM5502_REG_MANUAL_SW1_VBUSIN_SHIFT) +#define SM5502_REG_MANUAL_SW1_DP_MASK (0x7 << SM5502_REG_MANUAL_SW1_DP_SHIFT) +#define SM5502_REG_MANUAL_SW1_DM_MASK (0x7 << SM5502_REG_MANUAL_SW1_DM_SHIFT) +#define VBUSIN_SWITCH_OPEN 0x0 +#define VBUSIN_SWITCH_VBUSOUT 0x1 +#define VBUSIN_SWITCH_MIC 0x2 +#define VBUSIN_SWITCH_VBUSOUT_WITH_USB 0x3 +#define DM_DP_CON_SWITCH_OPEN 0x0 +#define DM_DP_CON_SWITCH_USB 0x1 +#define DM_DP_CON_SWITCH_AUDIO 0x2 +#define DM_DP_CON_SWITCH_UART 0x3 +#define DM_DP_SWITCH_OPEN ((DM_DP_CON_SWITCH_OPEN < Date: Tue, 12 Aug 2014 10:15:39 +0900 Subject: extcon: sm5502: Clean up codes by using checkpatch script This patch just clean up codes by using checkpatch script and fix warning message about if statement. - the result of checkpatch script as following: WARNING: void function return statements are not generally useful + return; +} WARNING: quoted string split across lines + dev_err(info->dev, "failed: irq request (IRQ: %d," + " error :%d)\n", muic_irq->irq, ret); - warning message about coding style. drivers/extcon/extcon-sm5502.c:398 sm5502_muic_cable_handler() warn: we tested 'attached' before and it was 'false' Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-sm5502.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c index f94d66aae9e3..8e6e66942d61 100644 --- a/drivers/extcon/extcon-sm5502.c +++ b/drivers/extcon/extcon-sm5502.c @@ -391,7 +391,7 @@ static int sm5502_muic_cable_handler(struct sm5502_muic_info *info, /* Get the type of attached or detached cable */ if (attached) cable_type = sm5502_muic_get_cable_type(info); - else if (!attached) + else cable_type = prev_cable_type; prev_cable_type = cable_type; @@ -453,8 +453,6 @@ static void sm5502_muic_irq_work(struct work_struct *work) dev_err(info->dev, "failed to handle MUIC interrupt\n"); mutex_unlock(&info->mutex); - - return; } /* @@ -613,8 +611,9 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c, IRQF_NO_SUSPEND, muic_irq->name, info); if (ret) { - dev_err(info->dev, "failed: irq request (IRQ: %d," - " error :%d)\n", muic_irq->irq, ret); + dev_err(info->dev, + "failed: irq request (IRQ: %d, error :%d)\n", + muic_irq->irq, ret); return ret; } } -- cgit v1.2.3 From c03e017c4d3d0fb783cbe6b7b9e4f278addcb23a Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 18 Aug 2014 09:05:21 +0900 Subject: extcon: rt8973a: Add Richtek RT8973A extcon driver This patch add support for Richtek RT8973A which is Micro USB Switch OVP and i2c interface. The RT8973A is a USB port accessory detector and switch that is optimized to protect low voltage system from abnormal high input voltage (up to 28V) and supports high speed USB operation. Also, RT8973A support 'auto-configuration' mode. If auto-configuration mode is enabled, RT8973A would control internal h/w patch for USB D-/D+ switching. Signed-off-by: Chanwoo Choi Signed-off-by: Seung-Woo Kim Acked-by: Kyungmin Park --- drivers/extcon/Kconfig | 12 + drivers/extcon/Makefile | 1 + drivers/extcon/extcon-rt8973a.c | 740 ++++++++++++++++++++++++++++++++++++++++ drivers/extcon/extcon-rt8973a.h | 203 +++++++++++ 4 files changed, 956 insertions(+) create mode 100644 drivers/extcon/extcon-rt8973a.c create mode 100644 drivers/extcon/extcon-rt8973a.h diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index 764f3a113e0a..6a1f7de6fa54 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig @@ -70,6 +70,18 @@ config EXTCON_PALMAS Say Y here to enable support for USB peripheral and USB host detection by palmas usb. +config EXTCON_RT8973A + tristate "RT8973A EXTCON support" + depends on I2C + select IRQ_DOMAIN + select REGMAP_I2C + select REGMAP_IRQ + help + If you say yes here you get support for the MUIC device of + Richtek RT8973A. The RT8973A is a USB port accessory detector + and switch that is optimized to protect low voltage system + from abnormal high input voltage (up to 28V). + config EXTCON_SM5502 tristate "SM5502 EXTCON support" depends on I2C diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile index b38546eb522a..0370b42e5a27 100644 --- a/drivers/extcon/Makefile +++ b/drivers/extcon/Makefile @@ -10,4 +10,5 @@ obj-$(CONFIG_EXTCON_MAX14577) += extcon-max14577.o obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o obj-$(CONFIG_EXTCON_PALMAS) += extcon-palmas.o +obj-$(CONFIG_EXTCON_RT8973A) += extcon-rt8973a.o obj-$(CONFIG_EXTCON_SM5502) += extcon-sm5502.o diff --git a/drivers/extcon/extcon-rt8973a.c b/drivers/extcon/extcon-rt8973a.c new file mode 100644 index 000000000000..a784b2d5ee72 --- /dev/null +++ b/drivers/extcon/extcon-rt8973a.c @@ -0,0 +1,740 @@ +/* + * extcon-rt8973a.c - Richtek RT8973A extcon driver to support USB switches + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd + * Author: Chanwoo Choi + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "extcon-rt8973a.h" + +#define DELAY_MS_DEFAULT 20000 /* unit: millisecond */ + +struct muic_irq { + unsigned int irq; + const char *name; + unsigned int virq; +}; + +struct reg_data { + u8 reg; + u8 mask; + u8 val; + bool invert; +}; + +struct rt8973a_muic_info { + struct device *dev; + struct extcon_dev *edev; + + struct i2c_client *i2c; + struct regmap *regmap; + + struct regmap_irq_chip_data *irq_data; + struct muic_irq *muic_irqs; + unsigned int num_muic_irqs; + int irq; + bool irq_attach; + bool irq_detach; + bool irq_ovp; + bool irq_otp; + struct work_struct irq_work; + + struct reg_data *reg_data; + unsigned int num_reg_data; + bool auto_config; + + struct mutex mutex; + + /* + * Use delayed workqueue to detect cable state and then + * notify cable state to notifiee/platform through uevent. + * After completing the booting of platform, the extcon provider + * driver should notify cable state to upper layer. + */ + struct delayed_work wq_detcable; +}; + +/* Default value of RT8973A register to bring up MUIC device. */ +static struct reg_data rt8973a_reg_data[] = { + { + .reg = RT8973A_REG_CONTROL1, + .mask = RT8973A_REG_CONTROL1_ADC_EN_MASK + | RT8973A_REG_CONTROL1_USB_CHD_EN_MASK + | RT8973A_REG_CONTROL1_CHGTYP_MASK + | RT8973A_REG_CONTROL1_SWITCH_OPEN_MASK + | RT8973A_REG_CONTROL1_AUTO_CONFIG_MASK + | RT8973A_REG_CONTROL1_INTM_MASK, + .val = RT8973A_REG_CONTROL1_ADC_EN_MASK + | RT8973A_REG_CONTROL1_USB_CHD_EN_MASK + | RT8973A_REG_CONTROL1_CHGTYP_MASK, + .invert = false, + }, + { /* sentinel */ } +}; + +/* List of detectable cables */ +enum { + EXTCON_CABLE_USB = 0, + EXTCON_CABLE_USB_HOST, + EXTCON_CABLE_TA, + EXTCON_CABLE_JIG_OFF_USB, + EXTCON_CABLE_JIG_ON_USB, + EXTCON_CABLE_JIG_OFF_UART, + EXTCON_CABLE_JIG_ON_UART, + + EXTCON_CABLE_END, +}; + +static const char *rt8973a_extcon_cable[] = { + [EXTCON_CABLE_USB] = "USB", + [EXTCON_CABLE_USB_HOST] = "USB-Host", + [EXTCON_CABLE_TA] = "TA", + [EXTCON_CABLE_JIG_OFF_USB] = "JIG-USB-OFF", + [EXTCON_CABLE_JIG_ON_USB] = "JIG-USB-ON", + [EXTCON_CABLE_JIG_OFF_UART] = "JIG-UART-OFF", + [EXTCON_CABLE_JIG_ON_UART] = "JIG-UART-ON", + NULL, +}; + +/* Define OVP (Over Voltage Protection), OTP (Over Temperature Protection) */ +enum rt8973a_event_type { + RT8973A_EVENT_ATTACH = 1, + RT8973A_EVENT_DETACH, + RT8973A_EVENT_OVP, + RT8973A_EVENT_OTP, +}; + +/* Define supported accessory type */ +enum rt8973a_muic_acc_type { + RT8973A_MUIC_ADC_OTG = 0x0, + RT8973A_MUIC_ADC_AUDIO_SEND_END_BUTTON, + RT8973A_MUIC_ADC_AUDIO_REMOTE_S1_BUTTON, + RT8973A_MUIC_ADC_AUDIO_REMOTE_S2_BUTTON, + RT8973A_MUIC_ADC_AUDIO_REMOTE_S3_BUTTON, + RT8973A_MUIC_ADC_AUDIO_REMOTE_S4_BUTTON, + RT8973A_MUIC_ADC_AUDIO_REMOTE_S5_BUTTON, + RT8973A_MUIC_ADC_AUDIO_REMOTE_S6_BUTTON, + RT8973A_MUIC_ADC_AUDIO_REMOTE_S7_BUTTON, + RT8973A_MUIC_ADC_AUDIO_REMOTE_S8_BUTTON, + RT8973A_MUIC_ADC_AUDIO_REMOTE_S9_BUTTON, + RT8973A_MUIC_ADC_AUDIO_REMOTE_S10_BUTTON, + RT8973A_MUIC_ADC_AUDIO_REMOTE_S11_BUTTON, + RT8973A_MUIC_ADC_AUDIO_REMOTE_S12_BUTTON, + RT8973A_MUIC_ADC_RESERVED_ACC_1, + RT8973A_MUIC_ADC_RESERVED_ACC_2, + RT8973A_MUIC_ADC_RESERVED_ACC_3, + RT8973A_MUIC_ADC_RESERVED_ACC_4, + RT8973A_MUIC_ADC_RESERVED_ACC_5, + RT8973A_MUIC_ADC_AUDIO_TYPE2, + RT8973A_MUIC_ADC_PHONE_POWERED_DEV, + RT8973A_MUIC_ADC_UNKNOWN_ACC_1, + RT8973A_MUIC_ADC_UNKNOWN_ACC_2, + RT8973A_MUIC_ADC_TA, + RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB, + RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB, + RT8973A_MUIC_ADC_UNKNOWN_ACC_3, + RT8973A_MUIC_ADC_UNKNOWN_ACC_4, + RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART, + RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART, + RT8973A_MUIC_ADC_UNKNOWN_ACC_5, + RT8973A_MUIC_ADC_OPEN = 0x1f, + + /* The below accessories has same ADC value (0x1f). + So, Device type1 is used to separate specific accessory. */ + /* |---------|--ADC| */ + /* | [7:5]|[4:0]| */ + RT8973A_MUIC_ADC_USB = 0x3f, /* | 001|11111| */ +}; + +/* List of supported interrupt for RT8973A */ +static struct muic_irq rt8973a_muic_irqs[] = { + { RT8973A_INT1_ATTACH, "muic-attach" }, + { RT8973A_INT1_DETACH, "muic-detach" }, + { RT8973A_INT1_CHGDET, "muic-chgdet" }, + { RT8973A_INT1_DCD_T, "muic-dcd-t" }, + { RT8973A_INT1_OVP, "muic-ovp" }, + { RT8973A_INT1_CONNECT, "muic-connect" }, + { RT8973A_INT1_ADC_CHG, "muic-adc-chg" }, + { RT8973A_INT1_OTP, "muic-otp" }, + { RT8973A_INT2_UVLO, "muic-uvlo" }, + { RT8973A_INT2_POR, "muic-por" }, + { RT8973A_INT2_OTP_FET, "muic-otp-fet" }, + { RT8973A_INT2_OVP_FET, "muic-ovp-fet" }, + { RT8973A_INT2_OCP_LATCH, "muic-ocp-latch" }, + { RT8973A_INT2_OCP, "muic-ocp" }, + { RT8973A_INT2_OVP_OCP, "muic-ovp-ocp" }, +}; + +/* Define interrupt list of RT8973A to register regmap_irq */ +static const struct regmap_irq rt8973a_irqs[] = { + /* INT1 interrupts */ + { .reg_offset = 0, .mask = RT8973A_INT1_ATTACH_MASK, }, + { .reg_offset = 0, .mask = RT8973A_INT1_DETACH_MASK, }, + { .reg_offset = 0, .mask = RT8973A_INT1_CHGDET_MASK, }, + { .reg_offset = 0, .mask = RT8973A_INT1_DCD_T_MASK, }, + { .reg_offset = 0, .mask = RT8973A_INT1_OVP_MASK, }, + { .reg_offset = 0, .mask = RT8973A_INT1_CONNECT_MASK, }, + { .reg_offset = 0, .mask = RT8973A_INT1_ADC_CHG_MASK, }, + { .reg_offset = 0, .mask = RT8973A_INT1_OTP_MASK, }, + + /* INT2 interrupts */ + { .reg_offset = 1, .mask = RT8973A_INT2_UVLOT_MASK,}, + { .reg_offset = 1, .mask = RT8973A_INT2_POR_MASK, }, + { .reg_offset = 1, .mask = RT8973A_INT2_OTP_FET_MASK, }, + { .reg_offset = 1, .mask = RT8973A_INT2_OVP_FET_MASK, }, + { .reg_offset = 1, .mask = RT8973A_INT2_OCP_LATCH_MASK, }, + { .reg_offset = 1, .mask = RT8973A_INT2_OCP_MASK, }, + { .reg_offset = 1, .mask = RT8973A_INT2_OVP_OCP_MASK, }, +}; + +static const struct regmap_irq_chip rt8973a_muic_irq_chip = { + .name = "rt8973a", + .status_base = RT8973A_REG_INT1, + .mask_base = RT8973A_REG_INTM1, + .mask_invert = false, + .num_regs = 2, + .irqs = rt8973a_irqs, + .num_irqs = ARRAY_SIZE(rt8973a_irqs), +}; + +/* Define regmap configuration of RT8973A for I2C communication */ +static bool rt8973a_muic_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case RT8973A_REG_INTM1: + case RT8973A_REG_INTM2: + return true; + default: + break; + } + return false; +} + +static const struct regmap_config rt8973a_muic_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .volatile_reg = rt8973a_muic_volatile_reg, + .max_register = RT8973A_REG_END, +}; + +/* Change DM_CON/DP_CON/VBUSIN switch according to cable type */ +static int rt8973a_muic_set_path(struct rt8973a_muic_info *info, + unsigned int con_sw, bool attached) +{ + int ret; + + /* + * Don't need to set h/w path according to cable type + * if Auto-configuration mode of CONTROL1 register is true. + */ + if (info->auto_config) + return 0; + + if (!attached) + con_sw = DM_DP_SWITCH_UART; + + switch (con_sw) { + case DM_DP_SWITCH_OPEN: + case DM_DP_SWITCH_USB: + case DM_DP_SWITCH_UART: + ret = regmap_update_bits(info->regmap, RT8973A_REG_MANUAL_SW1, + RT8973A_REG_MANUAL_SW1_DP_MASK | + RT8973A_REG_MANUAL_SW1_DM_MASK, + con_sw); + if (ret < 0) { + dev_err(info->dev, + "cannot update DM_CON/DP_CON switch\n"); + return ret; + } + break; + default: + dev_err(info->dev, "Unknown DM_CON/DP_CON switch type (%d)\n", + con_sw); + return -EINVAL; + } + + return 0; +} + +static int rt8973a_muic_get_cable_type(struct rt8973a_muic_info *info) +{ + unsigned int adc, dev1; + int ret, cable_type; + + /* Read ADC value according to external cable or button */ + ret = regmap_read(info->regmap, RT8973A_REG_ADC, &adc); + if (ret) { + dev_err(info->dev, "failed to read ADC register\n"); + return ret; + } + cable_type = adc & RT8973A_REG_ADC_MASK; + + /* Read Device 1 reigster to identify correct cable type */ + ret = regmap_read(info->regmap, RT8973A_REG_DEV1, &dev1); + if (ret) { + dev_err(info->dev, "failed to read DEV1 register\n"); + return ret; + } + + switch (adc) { + case RT8973A_MUIC_ADC_OPEN: + if (dev1 & RT8973A_REG_DEV1_USB_MASK) + cable_type = RT8973A_MUIC_ADC_USB; + else if (dev1 & RT8973A_REG_DEV1_DCPORT_MASK) + cable_type = RT8973A_MUIC_ADC_TA; + else + cable_type = RT8973A_MUIC_ADC_OPEN; + break; + default: + break; + } + + return cable_type; +} + +static int rt8973a_muic_cable_handler(struct rt8973a_muic_info *info, + enum rt8973a_event_type event) +{ + static unsigned int prev_cable_type; + const char **cable_names = info->edev->supported_cable; + unsigned int con_sw = DM_DP_SWITCH_UART; + int ret, idx = 0, cable_type; + bool attached = false; + + if (!cable_names) + return 0; + + switch (event) { + case RT8973A_EVENT_ATTACH: + cable_type = rt8973a_muic_get_cable_type(info); + attached = true; + break; + case RT8973A_EVENT_DETACH: + cable_type = prev_cable_type; + attached = false; + break; + case RT8973A_EVENT_OVP: + case RT8973A_EVENT_OTP: + dev_warn(info->dev, + "happen Over %s issue. Need to disconnect all cables\n", + event == RT8973A_EVENT_OVP ? "Voltage" : "Temperature"); + cable_type = prev_cable_type; + attached = false; + break; + default: + dev_err(info->dev, + "Cannot handle this event (event:%d)\n", event); + return -EINVAL; + } + prev_cable_type = cable_type; + + switch (cable_type) { + case RT8973A_MUIC_ADC_OTG: + idx = EXTCON_CABLE_USB_HOST; + con_sw = DM_DP_SWITCH_USB; + break; + case RT8973A_MUIC_ADC_TA: + idx = EXTCON_CABLE_TA; + con_sw = DM_DP_SWITCH_OPEN; + break; + case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB: + idx = EXTCON_CABLE_JIG_OFF_USB; + con_sw = DM_DP_SWITCH_UART; + break; + case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB: + idx = EXTCON_CABLE_JIG_ON_USB; + con_sw = DM_DP_SWITCH_UART; + break; + case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART: + idx = EXTCON_CABLE_JIG_OFF_UART; + con_sw = DM_DP_SWITCH_UART; + break; + case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART: + idx = EXTCON_CABLE_JIG_ON_UART; + con_sw = DM_DP_SWITCH_UART; + break; + case RT8973A_MUIC_ADC_USB: + idx = EXTCON_CABLE_USB; + con_sw = DM_DP_SWITCH_USB; + break; + case RT8973A_MUIC_ADC_OPEN: + return 0; + case RT8973A_MUIC_ADC_UNKNOWN_ACC_1: + case RT8973A_MUIC_ADC_UNKNOWN_ACC_2: + case RT8973A_MUIC_ADC_UNKNOWN_ACC_3: + case RT8973A_MUIC_ADC_UNKNOWN_ACC_4: + case RT8973A_MUIC_ADC_UNKNOWN_ACC_5: + dev_warn(info->dev, + "Unknown accessory type (adc:0x%x)\n", cable_type); + return 0; + case RT8973A_MUIC_ADC_AUDIO_SEND_END_BUTTON: + case RT8973A_MUIC_ADC_AUDIO_REMOTE_S1_BUTTON: + case RT8973A_MUIC_ADC_AUDIO_REMOTE_S2_BUTTON: + case RT8973A_MUIC_ADC_AUDIO_REMOTE_S3_BUTTON: + case RT8973A_MUIC_ADC_AUDIO_REMOTE_S4_BUTTON: + case RT8973A_MUIC_ADC_AUDIO_REMOTE_S5_BUTTON: + case RT8973A_MUIC_ADC_AUDIO_REMOTE_S6_BUTTON: + case RT8973A_MUIC_ADC_AUDIO_REMOTE_S7_BUTTON: + case RT8973A_MUIC_ADC_AUDIO_REMOTE_S8_BUTTON: + case RT8973A_MUIC_ADC_AUDIO_REMOTE_S9_BUTTON: + case RT8973A_MUIC_ADC_AUDIO_REMOTE_S10_BUTTON: + case RT8973A_MUIC_ADC_AUDIO_REMOTE_S11_BUTTON: + case RT8973A_MUIC_ADC_AUDIO_REMOTE_S12_BUTTON: + case RT8973A_MUIC_ADC_AUDIO_TYPE2: + dev_warn(info->dev, + "Audio device/button type (adc:0x%x)\n", cable_type); + return 0; + case RT8973A_MUIC_ADC_RESERVED_ACC_1: + case RT8973A_MUIC_ADC_RESERVED_ACC_2: + case RT8973A_MUIC_ADC_RESERVED_ACC_3: + case RT8973A_MUIC_ADC_RESERVED_ACC_4: + case RT8973A_MUIC_ADC_RESERVED_ACC_5: + case RT8973A_MUIC_ADC_PHONE_POWERED_DEV: + return 0; + default: + dev_err(info->dev, + "Cannot handle this cable_type (adc:0x%x)\n", + cable_type); + return -EINVAL; + } + + /* Change internal hardware path(DM_CON/DP_CON) */ + ret = rt8973a_muic_set_path(info, con_sw, attached); + if (ret < 0) + return ret; + + /* Change the state of external accessory */ + extcon_set_cable_state(info->edev, cable_names[idx], attached); + + return 0; +} + +static void rt8973a_muic_irq_work(struct work_struct *work) +{ + struct rt8973a_muic_info *info = container_of(work, + struct rt8973a_muic_info, irq_work); + int ret = 0; + + if (!info->edev) + return; + + mutex_lock(&info->mutex); + + /* Detect attached or detached cables */ + if (info->irq_attach) { + ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_ATTACH); + info->irq_attach = false; + } + + if (info->irq_detach) { + ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_DETACH); + info->irq_detach = false; + } + + if (info->irq_ovp) { + ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_OVP); + info->irq_ovp = false; + } + + if (info->irq_otp) { + ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_OTP); + info->irq_otp = false; + } + + if (ret < 0) + dev_err(info->dev, "failed to handle MUIC interrupt\n"); + + mutex_unlock(&info->mutex); +} + +static irqreturn_t rt8973a_muic_irq_handler(int irq, void *data) +{ + struct rt8973a_muic_info *info = data; + int i, irq_type = -1; + + for (i = 0; i < info->num_muic_irqs; i++) + if (irq == info->muic_irqs[i].virq) + irq_type = info->muic_irqs[i].irq; + + switch (irq_type) { + case RT8973A_INT1_ATTACH: + info->irq_attach = true; + break; + case RT8973A_INT1_DETACH: + info->irq_detach = true; + break; + case RT8973A_INT1_OVP: + info->irq_ovp = true; + break; + case RT8973A_INT1_OTP: + info->irq_otp = true; + break; + case RT8973A_INT1_CHGDET: + case RT8973A_INT1_DCD_T: + case RT8973A_INT1_CONNECT: + case RT8973A_INT1_ADC_CHG: + case RT8973A_INT2_UVLO: + case RT8973A_INT2_POR: + case RT8973A_INT2_OTP_FET: + case RT8973A_INT2_OVP_FET: + case RT8973A_INT2_OCP_LATCH: + case RT8973A_INT2_OCP: + case RT8973A_INT2_OVP_OCP: + default: + dev_dbg(info->dev, + "Cannot handle this interrupt (%d)\n", irq_type); + break; + } + + schedule_work(&info->irq_work); + + return IRQ_HANDLED; +} + +static void rt8973a_muic_detect_cable_wq(struct work_struct *work) +{ + struct rt8973a_muic_info *info = container_of(to_delayed_work(work), + struct rt8973a_muic_info, wq_detcable); + int ret; + + /* Notify the state of connector cable or not */ + ret = rt8973a_muic_cable_handler(info, RT8973A_EVENT_ATTACH); + if (ret < 0) + dev_warn(info->dev, "failed to detect cable state\n"); +} + +static void rt8973a_init_dev_type(struct rt8973a_muic_info *info) +{ + unsigned int data, vendor_id, version_id; + int i, ret; + + /* To test I2C, Print version_id and vendor_id of RT8973A */ + ret = regmap_read(info->regmap, RT8973A_REG_DEVICE_ID, &data); + if (ret) { + dev_err(info->dev, + "failed to read DEVICE_ID register: %d\n", ret); + return; + } + + vendor_id = ((data & RT8973A_REG_DEVICE_ID_VENDOR_MASK) >> + RT8973A_REG_DEVICE_ID_VENDOR_SHIFT); + version_id = ((data & RT8973A_REG_DEVICE_ID_VERSION_MASK) >> + RT8973A_REG_DEVICE_ID_VERSION_SHIFT); + + dev_info(info->dev, "Device type: version: 0x%x, vendor: 0x%x\n", + version_id, vendor_id); + + /* Initiazle the register of RT8973A device to bring-up */ + for (i = 0; i < info->num_reg_data; i++) { + u8 reg = info->reg_data[i].reg; + u8 mask = info->reg_data[i].mask; + u8 val = 0; + + if (info->reg_data[i].invert) + val = ~info->reg_data[i].val; + else + val = info->reg_data[i].val; + + regmap_update_bits(info->regmap, reg, mask, val); + } + + /* Check whether RT8973A is auto swithcing mode or not */ + ret = regmap_read(info->regmap, RT8973A_REG_CONTROL1, &data); + if (ret) { + dev_err(info->dev, + "failed to read CONTROL1 register: %d\n", ret); + return; + } + + data &= RT8973A_REG_CONTROL1_AUTO_CONFIG_MASK; + if (data) { + info->auto_config = true; + dev_info(info->dev, + "Enable Auto-configuration for internal path\n"); + } +} + +static int rt8973a_muic_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct device_node *np = i2c->dev.of_node; + struct rt8973a_muic_info *info; + int i, ret, irq_flags; + + if (!np) + return -EINVAL; + + info = devm_kzalloc(&i2c->dev, sizeof(*info), GFP_KERNEL); + if (!info) { + dev_err(&i2c->dev, "failed to allocate memory\n"); + return -ENOMEM; + } + i2c_set_clientdata(i2c, info); + + info->dev = &i2c->dev; + info->i2c = i2c; + info->irq = i2c->irq; + info->muic_irqs = rt8973a_muic_irqs; + info->num_muic_irqs = ARRAY_SIZE(rt8973a_muic_irqs); + info->reg_data = rt8973a_reg_data; + info->num_reg_data = ARRAY_SIZE(rt8973a_reg_data); + + mutex_init(&info->mutex); + + INIT_WORK(&info->irq_work, rt8973a_muic_irq_work); + + info->regmap = devm_regmap_init_i2c(i2c, &rt8973a_muic_regmap_config); + if (IS_ERR(info->regmap)) { + ret = PTR_ERR(info->regmap); + dev_err(info->dev, "failed to allocate register map: %d\n", + ret); + return ret; + } + + /* Support irq domain for RT8973A MUIC device */ + irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED; + ret = regmap_add_irq_chip(info->regmap, info->irq, irq_flags, 0, + &rt8973a_muic_irq_chip, &info->irq_data); + if (ret != 0) { + dev_err(info->dev, "failed to add irq_chip (irq:%d, err:%d)\n", + info->irq, ret); + return ret; + } + + for (i = 0; i < info->num_muic_irqs; i++) { + struct muic_irq *muic_irq = &info->muic_irqs[i]; + unsigned int virq = 0; + + virq = regmap_irq_get_virq(info->irq_data, muic_irq->irq); + if (virq <= 0) + return -EINVAL; + muic_irq->virq = virq; + + ret = devm_request_threaded_irq(info->dev, virq, NULL, + rt8973a_muic_irq_handler, + IRQF_NO_SUSPEND, + muic_irq->name, info); + if (ret) { + dev_err(info->dev, + "failed: irq request (IRQ: %d, error :%d)\n", + muic_irq->irq, ret); + return ret; + } + } + + /* Allocate extcon device */ + info->edev = devm_extcon_dev_allocate(info->dev, rt8973a_extcon_cable); + if (IS_ERR(info->edev)) { + dev_err(info->dev, "failed to allocate memory for extcon\n"); + return -ENOMEM; + } + info->edev->name = np->name; + + /* Register extcon device */ + ret = devm_extcon_dev_register(info->dev, info->edev); + if (ret) { + dev_err(info->dev, "failed to register extcon device\n"); + return ret; + } + + /* + * Detect accessory after completing the initialization of platform + * + * - Use delayed workqueue to detect cable state and then + * notify cable state to notifiee/platform through uevent. + * After completing the booting of platform, the extcon provider + * driver should notify cable state to upper layer. + */ + INIT_DELAYED_WORK(&info->wq_detcable, rt8973a_muic_detect_cable_wq); + queue_delayed_work(system_power_efficient_wq, &info->wq_detcable, + msecs_to_jiffies(DELAY_MS_DEFAULT)); + + /* Initialize RT8973A device and print vendor id and version id */ + rt8973a_init_dev_type(info); + + return 0; +} + +static int rt8973a_muic_i2c_remove(struct i2c_client *i2c) +{ + struct rt8973a_muic_info *info = i2c_get_clientdata(i2c); + + regmap_del_irq_chip(info->irq, info->irq_data); + + return 0; +} + +static struct of_device_id rt8973a_dt_match[] = { + { .compatible = "richtek,rt8973a-muic" }, + { }, +}; + +#ifdef CONFIG_PM_SLEEP +static int rt8973a_muic_suspend(struct device *dev) +{ + struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct rt8973a_muic_info *info = i2c_get_clientdata(i2c); + + enable_irq_wake(info->irq); + + return 0; +} + +static int rt8973a_muic_resume(struct device *dev) +{ + struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); + struct rt8973a_muic_info *info = i2c_get_clientdata(i2c); + + disable_irq_wake(info->irq); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(rt8973a_muic_pm_ops, + rt8973a_muic_suspend, rt8973a_muic_resume); + +static const struct i2c_device_id rt8973a_i2c_id[] = { + { "rt8973a", TYPE_RT8973A }, + { } +}; +MODULE_DEVICE_TABLE(i2c, rt8973a_i2c_id); + +static struct i2c_driver rt8973a_muic_i2c_driver = { + .driver = { + .name = "rt8973a", + .owner = THIS_MODULE, + .pm = &rt8973a_muic_pm_ops, + .of_match_table = rt8973a_dt_match, + }, + .probe = rt8973a_muic_i2c_probe, + .remove = rt8973a_muic_i2c_remove, + .id_table = rt8973a_i2c_id, +}; + +static int __init rt8973a_muic_i2c_init(void) +{ + return i2c_add_driver(&rt8973a_muic_i2c_driver); +} +subsys_initcall(rt8973a_muic_i2c_init); + +MODULE_DESCRIPTION("Richtek RT8973A Extcon driver"); +MODULE_AUTHOR("Chanwoo Choi "); +MODULE_LICENSE("GPL"); diff --git a/drivers/extcon/extcon-rt8973a.h b/drivers/extcon/extcon-rt8973a.h new file mode 100644 index 000000000000..9dc3e0227eb7 --- /dev/null +++ b/drivers/extcon/extcon-rt8973a.h @@ -0,0 +1,203 @@ +/* + * rt8973a.h + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd + * + * 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. + */ + +#ifndef __LINUX_EXTCON_RT8973A_H +#define __LINUX_EXTCON_RT8973A_H + +enum rt8973a_types { + TYPE_RT8973A, +}; + +/* RT8973A registers */ +enum rt8973A_reg { + RT8973A_REG_DEVICE_ID = 0x1, + RT8973A_REG_CONTROL1, + RT8973A_REG_INT1, + RT8973A_REG_INT2, + RT8973A_REG_INTM1, + RT8973A_REG_INTM2, + RT8973A_REG_ADC, + RT8973A_REG_RSVD_1, + RT8973A_REG_RSVD_2, + RT8973A_REG_DEV1, + RT8973A_REG_DEV2, + RT8973A_REG_RSVD_3, + RT8973A_REG_RSVD_4, + RT8973A_REG_RSVD_5, + RT8973A_REG_RSVD_6, + RT8973A_REG_RSVD_7, + RT8973A_REG_RSVD_8, + RT8973A_REG_RSVD_9, + RT8973A_REG_MANUAL_SW1, + RT8973A_REG_MANUAL_SW2, + RT8973A_REG_RSVD_10, + RT8973A_REG_RSVD_11, + RT8973A_REG_RSVD_12, + RT8973A_REG_RSVD_13, + RT8973A_REG_RSVD_14, + RT8973A_REG_RSVD_15, + RT8973A_REG_RESET, + + RT8973A_REG_END, +}; + +/* Define RT8973A MASK/SHIFT constant */ +#define RT8973A_REG_DEVICE_ID_VENDOR_SHIFT 0 +#define RT8973A_REG_DEVICE_ID_VERSION_SHIFT 3 +#define RT8973A_REG_DEVICE_ID_VENDOR_MASK (0x7 << RT8973A_REG_DEVICE_ID_VENDOR_SHIFT) +#define RT8973A_REG_DEVICE_ID_VERSION_MASK (0x1f << RT8973A_REG_DEVICE_ID_VERSION_SHIFT) + +#define RT8973A_REG_CONTROL1_INTM_SHIFT 0 +#define RT8973A_REG_CONTROL1_AUTO_CONFIG_SHIFT 2 +#define RT8973A_REG_CONTROL1_I2C_RST_EN_SHIFT 3 +#define RT8973A_REG_CONTROL1_SWITCH_OPEN_SHIFT 4 +#define RT8973A_REG_CONTROL1_CHGTYP_SHIFT 5 +#define RT8973A_REG_CONTROL1_USB_CHD_EN_SHIFT 6 +#define RT8973A_REG_CONTROL1_ADC_EN_SHIFT 7 +#define RT8973A_REG_CONTROL1_INTM_MASK (0x1 << RT8973A_REG_CONTROL1_INTM_SHIFT) +#define RT8973A_REG_CONTROL1_AUTO_CONFIG_MASK (0x1 << RT8973A_REG_CONTROL1_AUTO_CONFIG_SHIFT) +#define RT8973A_REG_CONTROL1_I2C_RST_EN_MASK (0x1 << RT8973A_REG_CONTROL1_I2C_RST_EN_SHIFT) +#define RT8973A_REG_CONTROL1_SWITCH_OPEN_MASK (0x1 << RT8973A_REG_CONTROL1_SWITCH_OPEN_SHIFT) +#define RT8973A_REG_CONTROL1_CHGTYP_MASK (0x1 << RT8973A_REG_CONTROL1_CHGTYP_SHIFT) +#define RT8973A_REG_CONTROL1_USB_CHD_EN_MASK (0x1 << RT8973A_REG_CONTROL1_USB_CHD_EN_SHIFT) +#define RT8973A_REG_CONTROL1_ADC_EN_MASK (0x1 << RT8973A_REG_CONTROL1_ADC_EN_SHIFT) + +#define RT9873A_REG_INTM1_ATTACH_SHIFT 0 +#define RT9873A_REG_INTM1_DETACH_SHIFT 1 +#define RT9873A_REG_INTM1_CHGDET_SHIFT 2 +#define RT9873A_REG_INTM1_DCD_T_SHIFT 3 +#define RT9873A_REG_INTM1_OVP_SHIFT 4 +#define RT9873A_REG_INTM1_CONNECT_SHIFT 5 +#define RT9873A_REG_INTM1_ADC_CHG_SHIFT 6 +#define RT9873A_REG_INTM1_OTP_SHIFT 7 +#define RT9873A_REG_INTM1_ATTACH_MASK (0x1 << RT9873A_REG_INTM1_ATTACH_SHIFT) +#define RT9873A_REG_INTM1_DETACH_MASK (0x1 << RT9873A_REG_INTM1_DETACH_SHIFT) +#define RT9873A_REG_INTM1_CHGDET_MASK (0x1 << RT9873A_REG_INTM1_CHGDET_SHIFT) +#define RT9873A_REG_INTM1_DCD_T_MASK (0x1 << RT9873A_REG_INTM1_DCD_T_SHIFT) +#define RT9873A_REG_INTM1_OVP_MASK (0x1 << RT9873A_REG_INTM1_OVP_SHIFT) +#define RT9873A_REG_INTM1_CONNECT_MASK (0x1 << RT9873A_REG_INTM1_CONNECT_SHIFT) +#define RT9873A_REG_INTM1_ADC_CHG_MASK (0x1 << RT9873A_REG_INTM1_ADC_CHG_SHIFT) +#define RT9873A_REG_INTM1_OTP_MASK (0x1 << RT9873A_REG_INTM1_OTP_SHIFT) + +#define RT9873A_REG_INTM2_UVLO_SHIFT 1 +#define RT9873A_REG_INTM2_POR_SHIFT 2 +#define RT9873A_REG_INTM2_OTP_FET_SHIFT 3 +#define RT9873A_REG_INTM2_OVP_FET_SHIFT 4 +#define RT9873A_REG_INTM2_OCP_LATCH_SHIFT 5 +#define RT9873A_REG_INTM2_OCP_SHIFT 6 +#define RT9873A_REG_INTM2_OVP_OCP_SHIFT 7 +#define RT9873A_REG_INTM2_UVLO_MASK (0x1 << RT9873A_REG_INTM2_UVLO_SHIFT) +#define RT9873A_REG_INTM2_POR_MASK (0x1 << RT9873A_REG_INTM2_POR_SHIFT) +#define RT9873A_REG_INTM2_OTP_FET_MASK (0x1 << RT9873A_REG_INTM2_OTP_FET_SHIFT) +#define RT9873A_REG_INTM2_OVP_FET_MASK (0x1 << RT9873A_REG_INTM2_OVP_FET_SHIFT) +#define RT9873A_REG_INTM2_OCP_LATCH_MASK (0x1 << RT9873A_REG_INTM2_OCP_LATCH_SHIFT) +#define RT9873A_REG_INTM2_OCP_MASK (0x1 << RT9873A_REG_INTM2_OCP_SHIFT) +#define RT9873A_REG_INTM2_OVP_OCP_MASK (0x1 << RT9873A_REG_INTM2_OVP_OCP_SHIFT) + +#define RT8973A_REG_ADC_SHIFT 0 +#define RT8973A_REG_ADC_MASK (0x1f << RT8973A_REG_ADC_SHIFT) + +#define RT8973A_REG_DEV1_OTG_SHIFT 0 +#define RT8973A_REG_DEV1_SDP_SHIFT 2 +#define RT8973A_REG_DEV1_UART_SHIFT 3 +#define RT8973A_REG_DEV1_CAR_KIT_TYPE1_SHIFT 4 +#define RT8973A_REG_DEV1_CDPORT_SHIFT 5 +#define RT8973A_REG_DEV1_DCPORT_SHIFT 6 +#define RT8973A_REG_DEV1_OTG_MASK (0x1 << RT8973A_REG_DEV1_OTG_SHIFT) +#define RT8973A_REG_DEV1_SDP_MASK (0x1 << RT8973A_REG_DEV1_SDP_SHIFT) +#define RT8973A_REG_DEV1_UART_MASK (0x1 << RT8973A_REG_DEV1_UART_SHIFT) +#define RT8973A_REG_DEV1_CAR_KIT_TYPE1_MASK (0x1 << RT8973A_REG_DEV1_CAR_KIT_TYPE1_SHIFT) +#define RT8973A_REG_DEV1_CDPORT_MASK (0x1 << RT8973A_REG_DEV1_CDPORT_SHIFT) +#define RT8973A_REG_DEV1_DCPORT_MASK (0x1 << RT8973A_REG_DEV1_DCPORT_SHIFT) +#define RT8973A_REG_DEV1_USB_MASK (RT8973A_REG_DEV1_SDP_MASK \ + | RT8973A_REG_DEV1_CDPORT_MASK) + +#define RT8973A_REG_DEV2_JIG_USB_ON_SHIFT 0 +#define RT8973A_REG_DEV2_JIG_USB_OFF_SHIFT 1 +#define RT8973A_REG_DEV2_JIG_UART_ON_SHIFT 2 +#define RT8973A_REG_DEV2_JIG_UART_OFF_SHIFT 3 +#define RT8973A_REG_DEV2_JIG_USB_ON_MASK (0x1 << RT8973A_REG_DEV2_JIG_USB_ON_SHIFT) +#define RT8973A_REG_DEV2_JIG_USB_OFF_MASK (0x1 << RT8973A_REG_DEV2_JIG_USB_OFF_SHIFT) +#define RT8973A_REG_DEV2_JIG_UART_ON_MASK (0x1 << RT8973A_REG_DEV2_JIG_UART_ON_SHIFT) +#define RT8973A_REG_DEV2_JIG_UART_OFF_MASK (0x1 << RT8973A_REG_DEV2_JIG_UART_OFF_SHIFT) + +#define RT8973A_REG_MANUAL_SW1_DP_SHIFT 2 +#define RT8973A_REG_MANUAL_SW1_DM_SHIFT 5 +#define RT8973A_REG_MANUAL_SW1_DP_MASK (0x7 << RT8973A_REG_MANUAL_SW1_DP_SHIFT) +#define RT8973A_REG_MANUAL_SW1_DM_MASK (0x7 << RT8973A_REG_MANUAL_SW1_DM_SHIFT) +#define DM_DP_CON_SWITCH_OPEN 0x0 +#define DM_DP_CON_SWITCH_USB 0x1 +#define DM_DP_CON_SWITCH_UART 0x3 +#define DM_DP_SWITCH_OPEN ((DM_DP_CON_SWITCH_OPEN << RT8973A_REG_MANUAL_SW1_DP_SHIFT) \ + | (DM_DP_CON_SWITCH_OPEN << RT8973A_REG_MANUAL_SW1_DM_SHIFT)) +#define DM_DP_SWITCH_USB ((DM_DP_CON_SWITCH_USB << RT8973A_REG_MANUAL_SW1_DP_SHIFT) \ + | (DM_DP_CON_SWITCH_USB << RT8973A_REG_MANUAL_SW1_DM_SHIFT)) +#define DM_DP_SWITCH_UART ((DM_DP_CON_SWITCH_UART << RT8973A_REG_MANUAL_SW1_DP_SHIFT) \ + | (DM_DP_CON_SWITCH_UART << RT8973A_REG_MANUAL_SW1_DM_SHIFT)) + +#define RT8973A_REG_MANUAL_SW2_FET_ON_SHIFT 0 +#define RT8973A_REG_MANUAL_SW2_JIG_ON_SHIFT 2 +#define RT8973A_REG_MANUAL_SW2_BOOT_SW_SHIFT 3 +#define RT8973A_REG_MANUAL_SW2_FET_ON_MASK (0x1 << RT8973A_REG_MANUAL_SW2_FET_ON_SHIFT) +#define RT8973A_REG_MANUAL_SW2_JIG_ON_MASK (0x1 << RT8973A_REG_MANUAL_SW2_JIG_ON_SHIFT) +#define RT8973A_REG_MANUAL_SW2_BOOT_SW_MASK (0x1 << RT8973A_REG_MANUAL_SW2_BOOT_SW_SHIFT) +#define RT8973A_REG_MANUAL_SW2_FET_ON 0 +#define RT8973A_REG_MANUAL_SW2_FET_OFF 0x1 +#define RT8973A_REG_MANUAL_SW2_JIG_OFF 0 +#define RT8973A_REG_MANUAL_SW2_JIG_ON 0x1 +#define RT8973A_REG_MANUAL_SW2_BOOT_SW_ON 0 +#define RT8973A_REG_MANUAL_SW2_BOOT_SW_OFF 0x1 + +#define RT8973A_REG_RESET_SHIFT 0 +#define RT8973A_REG_RESET_MASK (0x1 << RT8973A_REG_RESET_SHIFT) +#define RT8973A_REG_RESET 0x1 + +/* RT8973A Interrupts */ +enum rt8973a_irq { + /* Interrupt1*/ + RT8973A_INT1_ATTACH, + RT8973A_INT1_DETACH, + RT8973A_INT1_CHGDET, + RT8973A_INT1_DCD_T, + RT8973A_INT1_OVP, + RT8973A_INT1_CONNECT, + RT8973A_INT1_ADC_CHG, + RT8973A_INT1_OTP, + + /* Interrupt2*/ + RT8973A_INT2_UVLO, + RT8973A_INT2_POR, + RT8973A_INT2_OTP_FET, + RT8973A_INT2_OVP_FET, + RT8973A_INT2_OCP_LATCH, + RT8973A_INT2_OCP, + RT8973A_INT2_OVP_OCP, + + RT8973A_NUM, +}; + +#define RT8973A_INT1_ATTACH_MASK BIT(0) +#define RT8973A_INT1_DETACH_MASK BIT(1) +#define RT8973A_INT1_CHGDET_MASK BIT(2) +#define RT8973A_INT1_DCD_T_MASK BIT(3) +#define RT8973A_INT1_OVP_MASK BIT(4) +#define RT8973A_INT1_CONNECT_MASK BIT(5) +#define RT8973A_INT1_ADC_CHG_MASK BIT(6) +#define RT8973A_INT1_OTP_MASK BIT(7) +#define RT8973A_INT2_UVLOT_MASK BIT(0) +#define RT8973A_INT2_POR_MASK BIT(1) +#define RT8973A_INT2_OTP_FET_MASK BIT(2) +#define RT8973A_INT2_OVP_FET_MASK BIT(3) +#define RT8973A_INT2_OCP_LATCH_MASK BIT(4) +#define RT8973A_INT2_OCP_MASK BIT(5) +#define RT8973A_INT2_OVP_OCP_MASK BIT(6) + +#endif /* __LINUX_EXTCON_RT8973A_H */ -- cgit v1.2.3 From 6281100ec84016facda2bbbed5be649ff0f82073 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 4 Aug 2014 15:54:14 +0900 Subject: dt-bindings: extcon: Add support for Richtek RT8973A MUIC device This patch add documentation for binding of Richtek RT8973A (Micro USB Switch) device which is using EXTCON subsystem. The RT8973A device can detect various external accessories when external accessories is attached or detached. Signed-off-by: Chanwoo Choi Acked-by: Kyungmin Park --- .../devicetree/bindings/extcon/extcon-rt8973a.txt | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Documentation/devicetree/bindings/extcon/extcon-rt8973a.txt diff --git a/Documentation/devicetree/bindings/extcon/extcon-rt8973a.txt b/Documentation/devicetree/bindings/extcon/extcon-rt8973a.txt new file mode 100644 index 000000000000..6dede7d11532 --- /dev/null +++ b/Documentation/devicetree/bindings/extcon/extcon-rt8973a.txt @@ -0,0 +1,25 @@ + +* Richtek RT8973A - Micro USB Switch device + +The Richtek RT8973A is Micro USB Switch with OVP and I2C interface. The RT8973A +is a USB port accessory detector and switch that is optimized to protect low +voltage system from abnormal high input voltage (up to 28V) and supports high +speed USB operation. Also, RT8973A support 'auto-configuration' mode. +If auto-configuration mode is enabled, RT8973A would control internal h/w patch +for USB D-/D+ switching. + +Required properties: +- compatible: Should be "richtek,rt8973a-muic" +- reg: Specifies the I2C slave address of the MUIC block. It should be 0x14 +- interrupt-parent: Specifies the phandle of the interrupt controller to which + the interrupts from rt8973a are delivered to. +- interrupts: Interrupt specifiers for detection interrupt sources. + +Example: + + rt8973a@14 { + compatible = "richtek,rt8973a-muic"; + interrupt-parent = <&gpx1>; + interrupts = <5 0>; + reg = <0x14>; + }; -- cgit v1.2.3 From d715523174479455b07a8baffbe63ff13e0695bf Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 12 Sep 2014 15:16:37 +0200 Subject: extcon: max77693: Use resource managed interrupt line Use resource managed interrupt line devm_request_threaded_irq() to simplify a little cleanup paths: - no goto to cleanup label, - simpler remove function. Overall the driver size is decreased by 11 line of code. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-max77693.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 77460f2c1ca1..0574154a94a9 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -1155,13 +1155,11 @@ static int max77693_muic_probe(struct platform_device *pdev) virq = regmap_irq_get_virq(max77693->irq_data_muic, muic_irq->irq); - if (!virq) { - ret = -EINVAL; - goto err_irq; - } + if (!virq) + return -EINVAL; muic_irq->virq = virq; - ret = request_threaded_irq(virq, NULL, + ret = devm_request_threaded_irq(&pdev->dev, virq, NULL, max77693_muic_irq_handler, IRQF_NO_SUSPEND, muic_irq->name, info); @@ -1170,7 +1168,7 @@ static int max77693_muic_probe(struct platform_device *pdev) "failed: irq request (IRQ: %d," " error :%d)\n", muic_irq->irq, ret); - goto err_irq; + return ret; } } @@ -1179,15 +1177,14 @@ static int max77693_muic_probe(struct platform_device *pdev) max77693_extcon_cable); if (IS_ERR(info->edev)) { dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); - ret = -ENOMEM; - goto err_irq; + return -ENOMEM; } info->edev->name = DEV_NAME; ret = devm_extcon_dev_register(&pdev->dev, info->edev); if (ret) { dev_err(&pdev->dev, "failed to register extcon device\n"); - goto err_irq; + return ret; } /* Initialize MUIC register by using platform data or default data */ @@ -1265,7 +1262,7 @@ static int max77693_muic_probe(struct platform_device *pdev) MAX77693_MUIC_REG_ID, &id); if (ret < 0) { dev_err(&pdev->dev, "failed to read revision number\n"); - goto err_irq; + return ret; } dev_info(info->dev, "device ID : 0x%x\n", id); @@ -1285,20 +1282,12 @@ static int max77693_muic_probe(struct platform_device *pdev) delay_jiffies); return ret; - -err_irq: - while (--i >= 0) - free_irq(muic_irqs[i].virq, info); - return ret; } static int max77693_muic_remove(struct platform_device *pdev) { struct max77693_muic_info *info = platform_get_drvdata(pdev); - int i; - for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) - free_irq(muic_irqs[i].virq, info); cancel_work_sync(&info->irq_work); input_unregister_device(info->dock); -- cgit v1.2.3 From b7c7e0865944131820e1a65ff3b08d94ae553d0f Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 16 Sep 2014 23:16:15 +0200 Subject: extcon: sm5502: Drop useless include Don't include when the driver does not use anything from this header file. Signed-off-by: Jean Delvare Acked-by: MyungJoo Ham Signed-off-by: Chanwoo Choi Cc: Chanwoo Choi Cc: MyungJoo Ham --- drivers/extcon/extcon-sm5502.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c index 8e6e66942d61..b0f7bd82af90 100644 --- a/drivers/extcon/extcon-sm5502.c +++ b/drivers/extcon/extcon-sm5502.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3 From dc6048d7231914a608938d330a5006f9929f76c7 Mon Sep 17 00:00:00 2001 From: Jonghwa Lee Date: Wed, 17 Sep 2014 12:58:43 +0900 Subject: extcon: max77693: Fix a bug occured at changing ADC debounce time. When it writes some value other than 0 to BTLDset and JIGset, muic device will be reset automatically. And it happens during updating ADC debounce time, because it shares same register. To update ADC debounce time without reset, set value only to ADCDbset and 0 to BTLDset and JIGset. Signed-off-by: Jonghwa Lee [Remove un-needed masking operation by Chanwoo Choi] Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-max77693.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 0574154a94a9..490e27475bac 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -255,10 +255,14 @@ static int max77693_muic_set_debounce_time(struct max77693_muic_info *info, case ADC_DEBOUNCE_TIME_10MS: case ADC_DEBOUNCE_TIME_25MS: case ADC_DEBOUNCE_TIME_38_62MS: - ret = regmap_update_bits(info->max77693->regmap_muic, - MAX77693_MUIC_REG_CTRL3, - CONTROL3_ADCDBSET_MASK, - time << CONTROL3_ADCDBSET_SHIFT); + /* + * Don't touch BTLDset, JIGset when you want to change adc + * debounce time. If it writes other than 0 to BTLDset, JIGset + * muic device will be reset and loose current state. + */ + ret = regmap_write(info->max77693->regmap_muic, + MAX77693_MUIC_REG_CTRL3, + time << CONTROL3_ADCDBSET_SHIFT); if (ret) { dev_err(info->dev, "failed to set ADC debounce time\n"); return ret; -- cgit v1.2.3 From 62364357c184db52d556f868e493963fac2aea78 Mon Sep 17 00:00:00 2001 From: George Cherian Date: Tue, 9 Sep 2014 09:44:34 +0530 Subject: extcon: gpio: Fix code cleanup This patch fixes following minor cleanup: - Order the include files in alphabetical order. - Fix description of state_off in extcon_gpio.h - Add a descrition for check_on_resume in extcon_gpio.h Signed-off-by: George Cherian [Modify the name/description of patch to keep standary codiyg style by Chanwoo Choi] Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-gpio.c | 10 +++++----- include/linux/extcon/extcon-gpio.h | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c index 5b7ec274cb63..72f19a37fd01 100644 --- a/drivers/extcon/extcon-gpio.c +++ b/drivers/extcon/extcon-gpio.c @@ -20,16 +20,16 @@ * */ -#include -#include +#include +#include +#include #include #include +#include +#include #include #include #include -#include -#include -#include struct gpio_extcon_data { struct extcon_dev *edev; diff --git a/include/linux/extcon/extcon-gpio.h b/include/linux/extcon/extcon-gpio.h index 8900fdf511c6..0b17ad43fbfc 100644 --- a/include/linux/extcon/extcon-gpio.h +++ b/include/linux/extcon/extcon-gpio.h @@ -34,8 +34,10 @@ * @irq_flags: IRQ Flags (e.g., IRQF_TRIGGER_LOW). * @state_on: print_state is overriden with state_on if attached. * If NULL, default method of extcon class is used. - * @state_off: print_state is overriden with state_on if detached. + * @state_off: print_state is overriden with state_off if detached. * If NUll, default method of extcon class is used. + * @check_on_resume: Boolean describing whether to check the state of gpio + * while resuming from sleep. * * Note that in order for state_on or state_off to be valid, both state_on * and state_off should be not NULL. If at least one of them is NULL, -- cgit v1.2.3 From 2c2b93ecace25c3720e68e6cd7ee47f38c1d2e90 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Tue, 12 Aug 2014 20:16:03 +0300 Subject: mei: me: wait for hw ready non-interruptible We cannot handle user interrupt in context of hw initialization so we only wait for time out which is reasonably short Also we don't need to check error from wait, only flag value. Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index a9a0d08f758e..caf0da335994 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -266,19 +266,14 @@ static bool mei_me_hw_is_ready(struct mei_device *dev) static int mei_me_hw_ready_wait(struct mei_device *dev) { - int err; - mutex_unlock(&dev->device_lock); - err = wait_event_interruptible_timeout(dev->wait_hw_ready, + wait_event_timeout(dev->wait_hw_ready, dev->recvd_hw_ready, mei_secs_to_jiffies(MEI_HW_READY_TIMEOUT)); mutex_lock(&dev->device_lock); - if (!err && !dev->recvd_hw_ready) { - if (!err) - err = -ETIME; - dev_err(&dev->pdev->dev, - "wait hw ready failed. status = %d\n", err); - return err; + if (!dev->recvd_hw_ready) { + dev_err(&dev->pdev->dev, "wait hw ready failed\n"); + return -ETIME; } dev->recvd_hw_ready = false; @@ -664,7 +659,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); dev->recvd_hw_ready = true; - wake_up_interruptible(&dev->wait_hw_ready); + wake_up(&dev->wait_hw_ready); } else { dev_dbg(&dev->pdev->dev, "Spurious Interrupt\n"); } -- cgit v1.2.3 From 5456796b1a2aedd2d6345944b73ac41aeb8cb589 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Thu, 14 Aug 2014 17:22:20 +0300 Subject: mei: amthif: use service function to flush amthif queue Replace open coded loop with an existing service function: mei_io_list_flush Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 2 +- drivers/misc/mei/client.h | 2 ++ drivers/misc/mei/interrupt.c | 13 ++----------- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 2da05c0e113d..3c5a1d328977 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -117,7 +117,7 @@ static void __mei_io_list_flush(struct mei_cl_cb *list, * @list: An instance of our list structure * @cl: host client */ -static inline void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl) +void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl) { __mei_io_list_flush(list, cl, false); } diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index 96d5de0389f9..bf2b0b1b493d 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h @@ -45,6 +45,8 @@ static inline void mei_io_list_init(struct mei_cl_cb *list) { INIT_LIST_HEAD(&list->list); } +void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl); + /* * MEI Host Client Functions */ diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 4e3cba6da3f5..19709b70874e 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -556,8 +556,6 @@ void mei_timer(struct work_struct *work) { unsigned long timeout; struct mei_cl *cl; - struct mei_cl_cb *cb_pos = NULL; - struct mei_cl_cb *cb_next = NULL; struct mei_device *dev = container_of(work, struct mei_device, timer_work.work); @@ -632,15 +630,8 @@ void mei_timer(struct work_struct *work) dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n"); - list_for_each_entry_safe(cb_pos, cb_next, - &dev->amthif_rd_complete_list.list, list) { - - cl = cb_pos->file_object->private_data; - - /* Finding the AMTHI entry. */ - if (cl == &dev->iamthif_cl) - list_del(&cb_pos->list); - } + mei_io_list_flush(&dev->amthif_rd_complete_list, + &dev->iamthif_cl); mei_io_cb_free(dev->iamthif_current_cb); dev->iamthif_current_cb = NULL; -- cgit v1.2.3 From 05e314e2535f1693098e58b0261169565a43bec1 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Thu, 14 Aug 2014 17:22:21 +0300 Subject: mei: amthif: don't check amthif client identity on amthif queues Amthif has its own queues therefore it is redundant to check the client type when processing the queues Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 0d6234db00fa..ab6095988620 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -130,12 +130,9 @@ struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev, struct file *file) { struct mei_cl_cb *cb; - - list_for_each_entry(cb, &dev->amthif_rd_complete_list.list, list) { - if (cb->cl && cb->cl == &dev->iamthif_cl && - cb->file_object == file) + list_for_each_entry(cb, &dev->amthif_rd_complete_list.list, list) + if (cb->file_object == file) return cb; - } return NULL; } @@ -168,8 +165,8 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, int i; /* Only possible if we are in timeout */ - if (!cl || cl != &dev->iamthif_cl) { - dev_dbg(&dev->pdev->dev, "bad file ext.\n"); + if (!cl) { + dev_err(&dev->pdev->dev, "bad file ext.\n"); return -ETIME; } @@ -371,8 +368,8 @@ int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb) */ void mei_amthif_run_next_cmd(struct mei_device *dev) { - struct mei_cl_cb *pos = NULL; - struct mei_cl_cb *next = NULL; + struct mei_cl_cb *cb; + struct mei_cl_cb *next; int status; if (!dev) @@ -388,19 +385,15 @@ void mei_amthif_run_next_cmd(struct mei_device *dev) dev_dbg(&dev->pdev->dev, "complete amthif cmd_list cb.\n"); - list_for_each_entry_safe(pos, next, &dev->amthif_cmd_list.list, list) { - list_del(&pos->list); - - if (pos->cl && pos->cl == &dev->iamthif_cl) { - status = mei_amthif_send_cmd(dev, pos); - if (status) { - dev_dbg(&dev->pdev->dev, - "amthif write failed status = %d\n", + list_for_each_entry_safe(cb, next, &dev->amthif_cmd_list.list, list) { + list_del(&cb->list); + if (!cb->cl) + continue; + status = mei_amthif_send_cmd(dev, cb); + if (status) + dev_warn(&dev->pdev->dev, "amthif write failed status = %d\n", status); - return; - } - break; - } + break; } } @@ -559,7 +552,7 @@ int mei_amthif_irq_read_msg(struct mei_device *dev, dev->iamthif_stall_timer = 0; cb->buf_idx = dev->iamthif_msg_buf_index; cb->read_time = jiffies; - if (dev->iamthif_ioctl && cb->cl == &dev->iamthif_cl) { + if (dev->iamthif_ioctl) { /* found the iamthif cb */ dev_dbg(&dev->pdev->dev, "complete the amthif read cb.\n "); dev_dbg(&dev->pdev->dev, "add the amthif read cb to complete.\n "); -- cgit v1.2.3 From 3438c1f3b7b3f18a85ea7ed3c2f70ffe387aeee9 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 21 Aug 2014 14:29:10 +0300 Subject: mei: use consistently me_addr in the hbm structures Use consistently me_addr name in hbm protocol structures to represent in firmware client address Signed-off-by: Tomas Winkler Signed-off-by: Alexander Usyskin Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hbm.c | 6 +++--- drivers/misc/mei/hw.h | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 804106209d76..68a1cba54022 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -288,7 +288,7 @@ static int mei_hbm_prop_req(struct mei_device *dev) prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; - prop_req->address = next_client_index; + prop_req->me_addr = next_client_index; ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); if (ret) { @@ -783,9 +783,9 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) return -EPROTO; } - if (me_client->client_id != props_res->address) { + if (me_client->client_id != props_res->me_addr) { dev_err(&dev->pdev->dev, "hbm: properties response: address mismatch %d ?= %d\n", - me_client->client_id, props_res->address); + me_client->client_id, props_res->me_addr); return -EPROTO; } diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h index dd448e58cc87..50526f92f092 100644 --- a/drivers/misc/mei/hw.h +++ b/drivers/misc/mei/hw.h @@ -206,14 +206,13 @@ struct mei_client_properties { struct hbm_props_request { u8 hbm_cmd; - u8 address; + u8 me_addr; u8 reserved[2]; } __packed; - struct hbm_props_response { u8 hbm_cmd; - u8 address; + u8 me_addr; u8 status; u8 reserved[1]; struct mei_client_properties client_properties; -- cgit v1.2.3 From 68d1aa65978b86b2ca5bdf7211b27cfd32c3212d Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 21 Aug 2014 14:29:11 +0300 Subject: mei: use wrapper for simple hbm client message Reduce few code lines by using wrappers for sending simple hbm client messages Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hbm.c | 51 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 68a1cba54022..2b4ea161d748 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -124,7 +124,7 @@ static int mei_hbm_me_cl_allocate(struct mei_device *dev) /** * mei_hbm_cl_hdr - construct client hbm header * - * @cl: - client + * @cl: client * @hbm_cmd: host bus message command * @buf: buffer for cl header * @len: buffer length @@ -141,6 +141,26 @@ void mei_hbm_cl_hdr(struct mei_cl *cl, u8 hbm_cmd, void *buf, size_t len) cmd->me_addr = cl->me_client_id; } +/** + * mei_hbm_cl_write - write simple hbm client message + * + * @dev: the device structure + * @cl: client + * @hbm_cmd: host bus message command + * @len: buffer length + */ +static inline +int mei_hbm_cl_write(struct mei_device *dev, + struct mei_cl *cl, u8 hbm_cmd, size_t len) +{ + struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; + + mei_hbm_hdr(mei_hdr, len); + mei_hbm_cl_hdr(cl, hbm_cmd, dev->wr_msg.data, len); + + return mei_write_message(dev, mei_hdr, dev->wr_msg.data); +} + /** * mei_hbm_cl_addr_equal - tells if they have the same address * @@ -365,15 +385,9 @@ static int mei_hbm_stop_req(struct mei_device *dev) */ int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl) { - struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; const size_t len = sizeof(struct hbm_flow_control); - - mei_hbm_hdr(mei_hdr, len); - mei_hbm_cl_hdr(cl, MEI_FLOW_CONTROL_CMD, dev->wr_msg.data, len); - cl_dbg(dev, cl, "sending flow control\n"); - - return mei_write_message(dev, mei_hdr, dev->wr_msg.data); + return mei_hbm_cl_write(dev, cl, MEI_FLOW_CONTROL_CMD, len); } /** @@ -452,13 +466,8 @@ static void mei_hbm_cl_flow_control_res(struct mei_device *dev, */ int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl) { - struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; const size_t len = sizeof(struct hbm_client_connect_request); - - mei_hbm_hdr(mei_hdr, len); - mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_REQ_CMD, dev->wr_msg.data, len); - - return mei_write_message(dev, mei_hdr, dev->wr_msg.data); + return mei_hbm_cl_write(dev, cl, CLIENT_DISCONNECT_REQ_CMD, len); } /** @@ -471,13 +480,8 @@ int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl) */ int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl) { - struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; const size_t len = sizeof(struct hbm_client_connect_response); - - mei_hbm_hdr(mei_hdr, len); - mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_RES_CMD, dev->wr_msg.data, len); - - return mei_write_message(dev, mei_hdr, dev->wr_msg.data); + return mei_hbm_cl_write(dev, cl, CLIENT_DISCONNECT_RES_CMD, len); } /** @@ -526,13 +530,8 @@ static void mei_hbm_cl_disconnect_res(struct mei_device *dev, */ int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl) { - struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr; const size_t len = sizeof(struct hbm_client_connect_request); - - mei_hbm_hdr(mei_hdr, len); - mei_hbm_cl_hdr(cl, CLIENT_CONNECT_REQ_CMD, dev->wr_msg.data, len); - - return mei_write_message(dev, mei_hdr, dev->wr_msg.data); + return mei_hbm_cl_write(dev, cl, CLIENT_CONNECT_REQ_CMD, len); } /** -- cgit v1.2.3 From d320832f64666089a06778782e42fac29abd7bf7 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 24 Aug 2014 12:08:55 +0300 Subject: mei: me_client lookup function to return me_client object For support of dynamic addition and removal of me clients it is more convenient to use a list instead of static array as is use now. As the first step of the transition to the new data structure we change the lookup function so it returns me client address instead of an index. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 29 +++++++++++------------------ drivers/misc/mei/bus.c | 10 +++++----- drivers/misc/mei/client.c | 43 ++++++++++++++++++++----------------------- drivers/misc/mei/client.h | 5 +++-- drivers/misc/mei/hbm.c | 23 +++++++++-------------- drivers/misc/mei/main.c | 30 ++++++++++++++---------------- drivers/misc/mei/nfc.c | 15 ++++++++------- drivers/misc/mei/wd.c | 8 ++++---- 8 files changed, 74 insertions(+), 89 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index ab6095988620..c1fc6dd8faae 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -68,27 +68,26 @@ void mei_amthif_reset_params(struct mei_device *dev) int mei_amthif_host_init(struct mei_device *dev) { struct mei_cl *cl = &dev->iamthif_cl; + struct mei_me_client *me_cl; unsigned char *msg_buf; - int ret, i; + int ret; dev->iamthif_state = MEI_IAMTHIF_IDLE; mei_cl_init(cl, dev); - i = mei_me_cl_by_uuid(dev, &mei_amthif_guid); - if (i < 0) { - dev_info(&dev->pdev->dev, - "amthif: failed to find the client %d\n", i); + me_cl = mei_me_cl_by_uuid(dev, &mei_amthif_guid); + if (!me_cl) { + dev_info(&dev->pdev->dev, "amthif: failed to find the client"); return -ENOTTY; } - cl->me_client_id = dev->me_clients[i].client_id; + cl->me_client_id = me_cl->client_id; /* Assign iamthif_mtu to the value received from ME */ - dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length; - dev_dbg(&dev->pdev->dev, "IAMTHIF_MTU = %d\n", - dev->me_clients[i].props.max_msg_length); + dev->iamthif_mtu = me_cl->props.max_msg_length; + dev_dbg(&dev->pdev->dev, "IAMTHIF_MTU = %d\n", dev->iamthif_mtu); kfree(dev->iamthif_msg_buf); dev->iamthif_msg_buf = NULL; @@ -157,12 +156,11 @@ struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev, int mei_amthif_read(struct mei_device *dev, struct file *file, char __user *ubuf, size_t length, loff_t *offset) { - int rets; - int wait_ret; - struct mei_cl_cb *cb = NULL; struct mei_cl *cl = file->private_data; + struct mei_cl_cb *cb; unsigned long timeout; - int i; + int rets; + int wait_ret; /* Only possible if we are in timeout */ if (!cl) { @@ -170,11 +168,6 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, return -ETIME; } - i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id); - if (i < 0) { - dev_dbg(&dev->pdev->dev, "amthif client not found.\n"); - return -ENOTTY; - } dev_dbg(&dev->pdev->dev, "checking amthif data\n"); cb = mei_amthif_find_read_list_entry(dev, file); diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 0e993ef28b94..c829676c4716 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -229,8 +229,8 @@ static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, bool blocking) { struct mei_device *dev; + struct mei_me_client *me_cl; struct mei_cl_cb *cb; - int id; int rets; if (WARN_ON(!cl || !cl->dev)) @@ -242,11 +242,11 @@ static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, return -ENODEV; /* Check if we have an ME client device */ - id = mei_me_cl_by_id(dev, cl->me_client_id); - if (id < 0) - return id; + me_cl = mei_me_cl_by_id(dev, cl->me_client_id); + if (!me_cl) + return -ENOTTY; - if (length > dev->me_clients[id].props.max_msg_length) + if (length > me_cl->props.max_msg_length) return -EFBIG; cb = mei_io_cb_init(cl, NULL); diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 3c5a1d328977..a20e6e9422f8 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -33,18 +33,19 @@ * * Locking: called under "dev->device_lock" lock * - * returns me client index or -ENOENT if not found + * returns me client or NULL if not found */ -int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *uuid) +struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev, + const uuid_le *uuid) { int i; for (i = 0; i < dev->me_clients_num; ++i) if (uuid_le_cmp(*uuid, dev->me_clients[i].props.protocol_name) == 0) - return i; + return &dev->me_clients[i]; - return -ENOENT; + return NULL; } @@ -56,18 +57,18 @@ int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *uuid) * * Locking: called under "dev->device_lock" lock * - * returns index on success, -ENOENT on failure. + * returns me client or NULL if not found */ -int mei_me_cl_by_id(struct mei_device *dev, u8 client_id) +struct mei_me_client *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) - return i; + return &dev->me_clients[i]; - return -ENOENT; + return NULL; } @@ -646,7 +647,6 @@ int mei_cl_flow_ctrl_creds(struct mei_cl *cl) { struct mei_device *dev; struct mei_me_client *me_cl; - int id; if (WARN_ON(!cl || !cl->dev)) return -EINVAL; @@ -659,13 +659,12 @@ int mei_cl_flow_ctrl_creds(struct mei_cl *cl) if (cl->mei_flow_ctrl_creds > 0) return 1; - id = mei_me_cl_by_id(dev, cl->me_client_id); - if (id < 0) { + me_cl = mei_me_cl_by_id(dev, cl->me_client_id); + if (!me_cl) { cl_err(dev, cl, "no such me client %d\n", cl->me_client_id); - return id; + return -ENOENT; } - me_cl = &dev->me_clients[id]; if (me_cl->mei_flow_ctrl_creds) { if (WARN_ON(me_cl->props.single_recv_buf == 0)) return -EINVAL; @@ -688,21 +687,19 @@ int mei_cl_flow_ctrl_reduce(struct mei_cl *cl) { struct mei_device *dev; struct mei_me_client *me_cl; - int id; if (WARN_ON(!cl || !cl->dev)) return -EINVAL; dev = cl->dev; - id = mei_me_cl_by_id(dev, cl->me_client_id); - if (id < 0) { + me_cl = mei_me_cl_by_id(dev, cl->me_client_id); + if (!me_cl) { cl_err(dev, cl, "no such me client %d\n", cl->me_client_id); - return id; + return -ENOENT; } - me_cl = &dev->me_clients[id]; - if (me_cl->props.single_recv_buf != 0) { + if (me_cl->props.single_recv_buf) { if (WARN_ON(me_cl->mei_flow_ctrl_creds <= 0)) return -EINVAL; me_cl->mei_flow_ctrl_creds--; @@ -725,8 +722,8 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) { struct mei_device *dev; struct mei_cl_cb *cb; + struct mei_me_client *me_cl; int rets; - int i; if (WARN_ON(!cl || !cl->dev)) return -ENODEV; @@ -740,8 +737,8 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) cl_dbg(dev, cl, "read is pending.\n"); return -EBUSY; } - i = mei_me_cl_by_id(dev, cl->me_client_id); - if (i < 0) { + me_cl = mei_me_cl_by_id(dev, cl->me_client_id); + if (!me_cl) { cl_err(dev, cl, "no such me client %d\n", cl->me_client_id); return -ENOTTY; } @@ -760,7 +757,7 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) } /* always allocate at least client max message */ - length = max_t(size_t, length, dev->me_clients[i].props.max_msg_length); + length = max_t(size_t, length, me_cl->props.max_msg_length); rets = mei_io_cb_alloc_resp_buf(cb, length); if (rets) goto out; diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index bf2b0b1b493d..ddb95b2ee2ac 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h @@ -24,8 +24,9 @@ #include "mei_dev.h" -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); +struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev, + const uuid_le *cuuid); +struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id); /* * MEI IO Functions diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 2b4ea161d748..0b21675967f9 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -402,25 +402,20 @@ static int mei_hbm_add_single_flow_creds(struct mei_device *dev, struct hbm_flow_control *flow) { struct mei_me_client *me_cl; - int id; - id = mei_me_cl_by_id(dev, flow->me_addr); - if (id < 0) { + me_cl = mei_me_cl_by_id(dev, flow->me_addr); + if (!me_cl) { dev_err(&dev->pdev->dev, "no such me client %d\n", flow->me_addr); - return id; + return -ENOENT; } - me_cl = &dev->me_clients[id]; - if (me_cl->props.single_recv_buf) { - me_cl->mei_flow_ctrl_creds++; - dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n", - flow->me_addr); - dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n", - me_cl->mei_flow_ctrl_creds); - } else { - BUG(); /* error in flow control */ - } + if (WARN_ON(me_cl->props.single_recv_buf == 0)) + return -EINVAL; + + me_cl->mei_flow_ctrl_creds++; + dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single) creds = %d.\n", + flow->me_addr, me_cl->mei_flow_ctrl_creds); return 0; } diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 401a3d526cd0..a65b7cc4a877 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -303,11 +303,11 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, size_t length, loff_t *offset) { struct mei_cl *cl = file->private_data; + struct mei_me_client *me_cl; struct mei_cl_cb *write_cb = NULL; struct mei_device *dev; unsigned long timeout = 0; int rets; - int id; if (WARN_ON(!cl || !cl->dev)) return -ENODEV; @@ -321,8 +321,8 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, goto out; } - id = mei_me_cl_by_id(dev, cl->me_client_id); - if (id < 0) { + me_cl = mei_me_cl_by_id(dev, cl->me_client_id); + if (!me_cl) { rets = -ENOTTY; goto out; } @@ -332,7 +332,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, goto out; } - if (length > dev->me_clients[id].props.max_msg_length) { + if (length > me_cl->props.max_msg_length) { rets = -EFBIG; goto out; } @@ -428,8 +428,8 @@ static int mei_ioctl_connect_client(struct file *file, { struct mei_device *dev; struct mei_client *client; + struct mei_me_client *me_cl; struct mei_cl *cl; - int i; int rets; cl = file->private_data; @@ -450,22 +450,22 @@ static int mei_ioctl_connect_client(struct file *file, } /* find ME client we're trying to connect to */ - i = mei_me_cl_by_uuid(dev, &data->in_client_uuid); - if (i < 0 || dev->me_clients[i].props.fixed_address) { + me_cl = mei_me_cl_by_uuid(dev, &data->in_client_uuid); + if (!me_cl || me_cl->props.fixed_address) { dev_dbg(&dev->pdev->dev, "Cannot connect to FW Client UUID = %pUl\n", &data->in_client_uuid); rets = -ENOTTY; goto end; } - cl->me_client_id = dev->me_clients[i].client_id; + cl->me_client_id = me_cl->client_id; dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n", cl->me_client_id); dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n", - dev->me_clients[i].props.protocol_version); + me_cl->props.protocol_version); dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n", - dev->me_clients[i].props.max_msg_length); + me_cl->props.max_msg_length); /* if we're connecting to amthif client then we will use the * existing connection @@ -484,10 +484,8 @@ static int mei_ioctl_connect_client(struct file *file, file->private_data = &dev->iamthif_cl; client = &data->out_client_properties; - client->max_msg_length = - dev->me_clients[i].props.max_msg_length; - client->protocol_version = - dev->me_clients[i].props.protocol_version; + client->max_msg_length = me_cl->props.max_msg_length; + client->protocol_version = me_cl->props.protocol_version; rets = dev->iamthif_cl.status; goto end; @@ -496,8 +494,8 @@ static int mei_ioctl_connect_client(struct file *file, /* prepare the output buffer */ client = &data->out_client_properties; - client->max_msg_length = dev->me_clients[i].props.max_msg_length; - client->protocol_version = dev->me_clients[i].props.protocol_version; + client->max_msg_length = me_cl->props.max_msg_length; + client->protocol_version = me_cl->props.protocol_version; dev_dbg(&dev->pdev->dev, "Can connect?\n"); diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c index 5ccc23bc7690..964b4c606646 100644 --- a/drivers/misc/mei/nfc.c +++ b/drivers/misc/mei/nfc.c @@ -480,7 +480,8 @@ int mei_nfc_host_init(struct mei_device *dev) { struct mei_nfc_dev *ndev = &nfc_dev; struct mei_cl *cl_info, *cl = NULL; - int i, ret; + struct mei_me_client *me_cl; + int ret; /* already initialized */ if (ndev->cl_info) @@ -498,14 +499,14 @@ int mei_nfc_host_init(struct mei_device *dev) } /* check for valid client id */ - i = mei_me_cl_by_uuid(dev, &mei_nfc_info_guid); - if (i < 0) { + me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_info_guid); + if (!me_cl) { dev_info(&dev->pdev->dev, "nfc: failed to find the client\n"); ret = -ENOTTY; goto err; } - cl_info->me_client_id = dev->me_clients[i].client_id; + cl_info->me_client_id = me_cl->client_id; ret = mei_cl_link(cl_info, MEI_HOST_CLIENT_ID_ANY); if (ret) @@ -516,14 +517,14 @@ int mei_nfc_host_init(struct mei_device *dev) list_add_tail(&cl_info->device_link, &dev->device_list); /* check for valid client id */ - i = mei_me_cl_by_uuid(dev, &mei_nfc_guid); - if (i < 0) { + me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_guid); + if (!me_cl) { dev_info(&dev->pdev->dev, "nfc: failed to find the client\n"); ret = -ENOTTY; goto err; } - cl->me_client_id = dev->me_clients[i].client_id; + cl->me_client_id = me_cl->client_id; ret = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY); if (ret) diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index a84a664dfccb..8b241eef35d2 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -59,7 +59,7 @@ static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout) int mei_wd_host_init(struct mei_device *dev) { struct mei_cl *cl = &dev->wd_cl; - int id; + struct mei_me_client *me_cl; int ret; mei_cl_init(cl, dev); @@ -69,13 +69,13 @@ int mei_wd_host_init(struct mei_device *dev) /* check for valid client id */ - id = mei_me_cl_by_uuid(dev, &mei_wd_guid); - if (id < 0) { + me_cl = mei_me_cl_by_uuid(dev, &mei_wd_guid); + if (!me_cl) { dev_info(&dev->pdev->dev, "wd: failed to find the client\n"); return -ENOTTY; } - cl->me_client_id = dev->me_clients[id].client_id; + cl->me_client_id = me_cl->client_id; ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID); -- cgit v1.2.3 From 5ca2d3882d60c040285d0b45df731e11f5da7c64 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 21 Aug 2014 14:29:13 +0300 Subject: mei: use list for me clients book keeping To support dynamic addition/remove of clients it is more convenient to use list instead of static array Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 34 ++++++------- drivers/misc/mei/debugfs.c | 19 ++++---- drivers/misc/mei/hbm.c | 116 +++++++++++++++++---------------------------- drivers/misc/mei/init.c | 1 + drivers/misc/mei/mei_dev.h | 4 +- 5 files changed, 71 insertions(+), 103 deletions(-) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index a20e6e9422f8..244b54692b48 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -38,12 +38,11 @@ struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *uuid) { - int i; + struct mei_me_client *me_cl; - for (i = 0; i < dev->me_clients_num; ++i) - if (uuid_le_cmp(*uuid, - dev->me_clients[i].props.protocol_name) == 0) - return &dev->me_clients[i]; + list_for_each_entry(me_cl, &dev->me_clients, list) + if (uuid_le_cmp(*uuid, me_cl->props.protocol_name) == 0) + return me_cl; return NULL; } @@ -62,12 +61,12 @@ struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev, struct mei_me_client *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) - return &dev->me_clients[i]; + struct mei_me_client *me_cl; + list_for_each_entry(me_cl, &dev->me_clients, list) + if (me_cl->client_id == client_id) + return me_cl; return NULL; } @@ -396,19 +395,19 @@ void mei_host_client_init(struct work_struct *work) { struct mei_device *dev = container_of(work, struct mei_device, init_work); - struct mei_client_properties *client_props; - int i; + struct mei_me_client *me_cl; + struct mei_client_properties *props; mutex_lock(&dev->device_lock); - for (i = 0; i < dev->me_clients_num; i++) { - client_props = &dev->me_clients[i].props; + list_for_each_entry(me_cl, &dev->me_clients, list) { + props = &me_cl->props; - if (!uuid_le_cmp(client_props->protocol_name, mei_amthif_guid)) + if (!uuid_le_cmp(props->protocol_name, mei_amthif_guid)) mei_amthif_host_init(dev); - else if (!uuid_le_cmp(client_props->protocol_name, mei_wd_guid)) + else if (!uuid_le_cmp(props->protocol_name, mei_wd_guid)) mei_wd_host_init(dev); - else if (!uuid_le_cmp(client_props->protocol_name, mei_nfc_guid)) + else if (!uuid_le_cmp(props->protocol_name, mei_nfc_guid)) mei_nfc_host_init(dev); } @@ -653,9 +652,6 @@ int mei_cl_flow_ctrl_creds(struct mei_cl *cl) dev = cl->dev; - if (!dev->me_clients_num) - return 0; - if (cl->mei_flow_ctrl_creds > 0) return 1; diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index ced5b777c70f..3b032881622d 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c @@ -28,10 +28,10 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf, size_t cnt, loff_t *ppos) { struct mei_device *dev = fp->private_data; - struct mei_me_client *cl; + struct mei_me_client *me_cl; const size_t bufsz = 1024; char *buf = kzalloc(bufsz, GFP_KERNEL); - int i; + int i = 0; int pos = 0; int ret; @@ -47,20 +47,19 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf, if (dev->dev_state != MEI_DEV_ENABLED) goto out; - for (i = 0; i < dev->me_clients_num; i++) { - cl = &dev->me_clients[i]; + list_for_each_entry(me_cl, &dev->me_clients, list) { /* skip me clients that cannot be connected */ - if (cl->props.max_number_of_connections == 0) + if (me_cl->props.max_number_of_connections == 0) continue; pos += scnprintf(buf + pos, bufsz - pos, "%2d|%2d|%4d|%pUl|%3d|%7d|\n", - i, cl->client_id, - cl->props.fixed_address, - &cl->props.protocol_name, - cl->props.max_number_of_connections, - cl->props.max_msg_length); + i++, me_cl->client_id, + me_cl->props.fixed_address, + &me_cl->props.protocol_name, + me_cl->props.max_number_of_connections, + me_cl->props.max_msg_length); } out: mutex_unlock(&dev->device_lock); diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 0b21675967f9..45659de14186 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -77,50 +77,19 @@ void mei_hbm_idle(struct mei_device *dev) */ void mei_hbm_reset(struct mei_device *dev) { - dev->me_clients_num = 0; + struct mei_me_client *me_cl, *next; + dev->me_client_presentation_num = 0; dev->me_client_index = 0; - kfree(dev->me_clients); - dev->me_clients = NULL; + list_for_each_entry_safe(me_cl, next, &dev->me_clients, list) { + list_del(&me_cl->list); + kfree(me_cl); + } mei_hbm_idle(dev); } -/** - * mei_hbm_me_cl_allocate - allocates storage for me clients - * - * @dev: the device structure - * - * returns 0 on success -ENOMEM on allocation failure - */ -static int mei_hbm_me_cl_allocate(struct mei_device *dev) -{ - struct mei_me_client *clients; - int b; - - mei_hbm_reset(dev); - - /* count how many ME clients we have */ - for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX) - dev->me_clients_num++; - - if (dev->me_clients_num == 0) - return 0; - - dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%ld.\n", - dev->me_clients_num * sizeof(struct mei_me_client)); - /* allocate storage for ME clients representation */ - clients = kcalloc(dev->me_clients_num, - sizeof(struct mei_me_client), GFP_KERNEL); - if (!clients) { - dev_err(&dev->pdev->dev, "memory allocation for ME clients failed.\n"); - return -ENOMEM; - } - dev->me_clients = clients; - return 0; -} - /** * mei_hbm_cl_hdr - construct client hbm header * @@ -213,6 +182,8 @@ int mei_hbm_start_req(struct mei_device *dev) const size_t len = sizeof(struct hbm_host_version_request); int ret; + mei_hbm_reset(dev); + mei_hbm_hdr(mei_hdr, len); /* host start message */ @@ -267,6 +238,32 @@ static int mei_hbm_enum_clients_req(struct mei_device *dev) return 0; } +/* + * mei_hbm_me_cl_add - add new me client to the list + * + * @dev: the device structure + * @res: hbm property response + * + * returns 0 on success and -ENOMEM on allocation failure + */ + +static int mei_hbm_me_cl_add(struct mei_device *dev, + struct hbm_props_response *res) +{ + struct mei_me_client *me_cl; + + me_cl = kzalloc(sizeof(struct mei_me_client), GFP_KERNEL); + if (!me_cl) + return -ENOMEM; + + me_cl->props = res->client_properties; + me_cl->client_id = res->me_addr; + me_cl->mei_flow_ctrl_creds = 0; + + list_add(&me_cl->list, &dev->me_clients); + return 0; +} + /** * mei_hbm_prop_req - request property for a single client * @@ -282,11 +279,8 @@ static int mei_hbm_prop_req(struct mei_device *dev) struct hbm_props_request *prop_req; const size_t len = sizeof(struct hbm_props_request); unsigned long next_client_index; - unsigned long client_num; int ret; - client_num = dev->me_client_presentation_num; - next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, dev->me_client_index); @@ -298,15 +292,11 @@ static int mei_hbm_prop_req(struct mei_device *dev) return 0; } - dev->me_clients[client_num].client_id = next_client_index; - dev->me_clients[client_num].mei_flow_ctrl_creds = 0; - mei_hbm_hdr(mei_hdr, len); prop_req = (struct hbm_props_request *)dev->wr_msg.data; memset(prop_req, 0, sizeof(struct hbm_props_request)); - prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; prop_req->me_addr = next_client_index; @@ -441,11 +431,10 @@ static void mei_hbm_cl_flow_control_res(struct mei_device *dev, list_for_each_entry(cl, &dev->file_list, link) { if (mei_hbm_cl_addr_equal(cl, flow_control)) { cl->mei_flow_ctrl_creds++; - dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n", - flow_control->host_addr, flow_control->me_addr); - dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n", - cl->mei_flow_ctrl_creds); - break; + dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d creds %d.\n", + flow_control->host_addr, flow_control->me_addr, + cl->mei_flow_ctrl_creds); + break; } } } @@ -641,7 +630,6 @@ bool mei_hbm_version_is_supported(struct mei_device *dev) int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) { struct mei_bus_message *mei_msg; - struct mei_me_client *me_client; struct hbm_host_version_response *version_res; struct hbm_client_connect_response *connect_res; struct hbm_client_connect_response *disconnect_res; @@ -763,13 +751,14 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) dev->init_clients_timer = 0; - if (dev->me_clients == NULL) { - dev_err(&dev->pdev->dev, "hbm: properties response: mei_clients not allocated\n"); + if (dev->dev_state != MEI_DEV_INIT_CLIENTS || + dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) { + dev_err(&dev->pdev->dev, "hbm: properties response: state mismatch, [%d, %d]\n", + dev->dev_state, dev->hbm_state); return -EPROTO; } props_res = (struct hbm_props_response *)mei_msg; - me_client = &dev->me_clients[dev->me_client_presentation_num]; if (props_res->status) { dev_err(&dev->pdev->dev, "hbm: properties response: wrong status = %d\n", @@ -777,20 +766,8 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) return -EPROTO; } - if (me_client->client_id != props_res->me_addr) { - dev_err(&dev->pdev->dev, "hbm: properties response: address mismatch %d ?= %d\n", - me_client->client_id, props_res->me_addr); - return -EPROTO; - } + mei_hbm_me_cl_add(dev, props_res); - if (dev->dev_state != MEI_DEV_INIT_CLIENTS || - dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) { - dev_err(&dev->pdev->dev, "hbm: properties response: state mismatch, [%d, %d]\n", - dev->dev_state, dev->hbm_state); - return -EPROTO; - } - - me_client->props = props_res->client_properties; dev->me_client_index++; dev->me_client_presentation_num++; @@ -809,7 +786,7 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) BUILD_BUG_ON(sizeof(dev->me_clients_map) < sizeof(enum_res->valid_addresses)); memcpy(dev->me_clients_map, enum_res->valid_addresses, - sizeof(enum_res->valid_addresses)); + sizeof(enum_res->valid_addresses)); if (dev->dev_state != MEI_DEV_INIT_CLIENTS || dev->hbm_state != MEI_HBM_ENUM_CLIENTS) { @@ -818,11 +795,6 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) return -EPROTO; } - if (mei_hbm_me_cl_allocate(dev)) { - dev_err(&dev->pdev->dev, "hbm: enumeration response: cannot allocate clients array\n"); - return -ENOMEM; - } - dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES; /* first property request */ diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 006929222481..73ccbb65d4ff 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -356,6 +356,7 @@ void mei_device_init(struct mei_device *dev, const struct mei_cfg *cfg) /* setup our list array */ INIT_LIST_HEAD(&dev->file_list); INIT_LIST_HEAD(&dev->device_list); + INIT_LIST_HEAD(&dev->me_clients); mutex_init(&dev->device_lock); init_waitqueue_head(&dev->wait_hw_ready); init_waitqueue_head(&dev->wait_pg); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 0b0d6135543b..76d8aa30e90d 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -175,6 +175,7 @@ struct mei_fw_status { * @mei_flow_ctrl_creds - flow control credits */ struct mei_me_client { + struct list_head list; struct mei_client_properties props; u8 client_id; u8 mei_flow_ctrl_creds; @@ -478,10 +479,9 @@ struct mei_device { struct hbm_version version; - struct mei_me_client *me_clients; /* Note: memory has to be allocated */ + struct list_head me_clients; DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX); - unsigned long me_clients_num; unsigned long me_client_presentation_num; unsigned long me_client_index; -- cgit v1.2.3 From 25ca6472b590e87efba314892a76bd5629c8c989 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 21 Aug 2014 14:29:14 +0300 Subject: mei: add me client remove functions To support dynamic addition/remove we add wrappers for removal of me clients Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 22 +++++++++++++++++++++- drivers/misc/mei/client.h | 2 ++ drivers/misc/mei/hbm.c | 21 +++++++++++++++------ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 244b54692b48..10d0a04f45d6 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -47,7 +47,6 @@ struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev, return NULL; } - /** * mei_me_cl_by_id return index to me_clients for client_id * @@ -70,6 +69,27 @@ struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id) return NULL; } +/** + * mei_me_cl_remove - remove me client matching uuid and client_id + * + * @dev: the device structure + * @uuid: me client uuid + * @client_id: me client address + */ +void mei_me_cl_remove(struct mei_device *dev, const uuid_le *uuid, u8 client_id) +{ + struct mei_me_client *me_cl, *next; + + list_for_each_entry_safe(me_cl, next, &dev->me_clients, list) { + if (uuid_le_cmp(*uuid, me_cl->props.protocol_name) == 0 && + me_cl->client_id == client_id) { + list_del(&me_cl->list); + kfree(me_cl); + break; + } + } +} + /** * mei_cl_cmp_id - tells if the clients are the same diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index ddb95b2ee2ac..8871a852cfbb 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h @@ -27,6 +27,8 @@ struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid); struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id); +void mei_me_cl_remove(struct mei_device *dev, + const uuid_le *uuid, u8 client_id); /* * MEI IO Functions diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 45659de14186..5fb177b3bfef 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -71,21 +71,30 @@ void mei_hbm_idle(struct mei_device *dev) } /** - * mei_hbm_reset - reset hbm counters and book keeping data structurs + * mei_me_cl_remove_all - remove all me clients * * @dev: the device structure */ -void mei_hbm_reset(struct mei_device *dev) +static void mei_me_cl_remove_all(struct mei_device *dev) { struct mei_me_client *me_cl, *next; + list_for_each_entry_safe(me_cl, next, &dev->me_clients, list) { + list_del(&me_cl->list); + kfree(me_cl); + } +} +/** + * mei_hbm_reset - reset hbm counters and book keeping data structurs + * + * @dev: the device structure + */ +void mei_hbm_reset(struct mei_device *dev) +{ dev->me_client_presentation_num = 0; dev->me_client_index = 0; - list_for_each_entry_safe(me_cl, next, &dev->me_clients, list) { - list_del(&me_cl->list); - kfree(me_cl); - } + mei_me_cl_remove_all(dev); mei_hbm_idle(dev); } -- cgit v1.2.3 From d880f3294d0576e79dfab4e2cd5a2eb62fe188f0 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 21 Aug 2014 14:29:15 +0300 Subject: mei: add mei_me_cl_by_uuid_id function When handling dynamic clients there might be a race scenario in which two me clients with the same me address would be linked in the me clients list, therefore we need to search by both uuid and me address. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 1 + drivers/misc/mei/bus.c | 4 ++-- drivers/misc/mei/client.c | 14 +++++++++++++- drivers/misc/mei/client.h | 4 ++++ drivers/misc/mei/main.c | 3 ++- drivers/misc/mei/mei_dev.h | 2 +- drivers/misc/mei/nfc.c | 6 ++---- drivers/misc/mei/wd.c | 1 + 8 files changed, 26 insertions(+), 9 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index c1fc6dd8faae..4114758cd1ce 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -83,6 +83,7 @@ int mei_amthif_host_init(struct mei_device *dev) } cl->me_client_id = me_cl->client_id; + cl->cl_uuid = me_cl->props.protocol_name; /* Assign iamthif_mtu to the value received from ME */ diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index c829676c4716..09dad2df7aae 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -147,7 +147,7 @@ static struct mei_cl *mei_bus_find_mei_cl_by_uuid(struct mei_device *dev, struct mei_cl *cl; list_for_each_entry(cl, &dev->device_list, device_link) { - if (!uuid_le_cmp(uuid, cl->device_uuid)) + if (!uuid_le_cmp(uuid, cl->cl_uuid)) return cl; } @@ -242,7 +242,7 @@ static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, return -ENODEV; /* Check if we have an ME client device */ - me_cl = mei_me_cl_by_id(dev, cl->me_client_id); + me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id); if (!me_cl) return -ENOTTY; diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 10d0a04f45d6..1a4dafb77205 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -69,6 +69,18 @@ struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id) return NULL; } +struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev, + const uuid_le *uuid, u8 client_id) +{ + struct mei_me_client *me_cl; + + list_for_each_entry(me_cl, &dev->me_clients, list) + if (uuid_le_cmp(*uuid, me_cl->props.protocol_name) == 0 && + me_cl->client_id == client_id) + return me_cl; + return NULL; +} + /** * mei_me_cl_remove - remove me client matching uuid and client_id * @@ -753,7 +765,7 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) cl_dbg(dev, cl, "read is pending.\n"); return -EBUSY; } - me_cl = mei_me_cl_by_id(dev, cl->me_client_id); + me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id); if (!me_cl) { cl_err(dev, cl, "no such me client %d\n", cl->me_client_id); return -ENOTTY; diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index 8871a852cfbb..f5d03d622923 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h @@ -27,6 +27,10 @@ struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid); struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id); + +struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev, + const uuid_le *uuid, u8 client_id); + void mei_me_cl_remove(struct mei_device *dev, const uuid_le *uuid, u8 client_id); diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index a65b7cc4a877..957f44aaa97a 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -321,7 +321,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, goto out; } - me_cl = mei_me_cl_by_id(dev, cl->me_client_id); + me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id); if (!me_cl) { rets = -ENOTTY; goto out; @@ -459,6 +459,7 @@ static int mei_ioctl_connect_client(struct file *file, } cl->me_client_id = me_cl->client_id; + cl->cl_uuid = me_cl->props.protocol_name; dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n", cl->me_client_id); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 76d8aa30e90d..9f684b9b3c93 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -212,6 +212,7 @@ struct mei_cl { wait_queue_head_t wait; int status; /* ID of client connected */ + uuid_le cl_uuid; u8 host_client_id; u8 me_client_id; u8 mei_flow_ctrl_creds; @@ -223,7 +224,6 @@ struct mei_cl { /* MEI CL bus data */ struct mei_cl_device *device; struct list_head device_link; - uuid_le device_uuid; }; /** struct mei_hw_ops diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c index 964b4c606646..e0e75d429fdf 100644 --- a/drivers/misc/mei/nfc.c +++ b/drivers/misc/mei/nfc.c @@ -507,12 +507,12 @@ int mei_nfc_host_init(struct mei_device *dev) } cl_info->me_client_id = me_cl->client_id; + cl_info->cl_uuid = me_cl->props.protocol_name; ret = mei_cl_link(cl_info, MEI_HOST_CLIENT_ID_ANY); if (ret) goto err; - cl_info->device_uuid = mei_nfc_info_guid; list_add_tail(&cl_info->device_link, &dev->device_list); @@ -525,14 +525,12 @@ int mei_nfc_host_init(struct mei_device *dev) } cl->me_client_id = me_cl->client_id; + cl->cl_uuid = me_cl->props.protocol_name; ret = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY); if (ret) goto err; - cl->device_uuid = mei_nfc_guid; - - list_add_tail(&cl->device_link, &dev->device_list); ndev->req_id = 1; diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 8b241eef35d2..40f46e4c2e9c 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -76,6 +76,7 @@ int mei_wd_host_init(struct mei_device *dev) } cl->me_client_id = me_cl->client_id; + cl->cl_uuid = me_cl->props.protocol_name; ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID); -- cgit v1.2.3 From 89778d6e2a39027977e2de822808bd82afd6ea46 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 21 Aug 2014 14:29:16 +0300 Subject: mei: add hbm commands return status values HBM uses global list of status values from which the values of particular commands are derived Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hbm.c | 22 ++++++++++++++++++++-- drivers/misc/mei/hw.h | 39 +++++++++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 5fb177b3bfef..d50c8d1fb36d 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -25,6 +25,23 @@ #include "hbm.h" #include "client.h" +static const char *mei_hbm_status_str(enum mei_hbm_status status) +{ +#define MEI_HBM_STATUS(status) case MEI_HBMS_##status: return #status + switch (status) { + MEI_HBM_STATUS(SUCCESS); + MEI_HBM_STATUS(CLIENT_NOT_FOUND); + MEI_HBM_STATUS(ALREADY_EXISTS); + MEI_HBM_STATUS(REJECTED); + MEI_HBM_STATUS(INVALID_PARAMETER); + MEI_HBM_STATUS(NOT_ALLOWED); + MEI_HBM_STATUS(ALREADY_STARTED); + MEI_HBM_STATUS(NOT_STARTED); + default: return "unknown"; + } +#undef MEI_HBM_STATUS +}; + static const char *mei_cl_conn_status_str(enum mei_cl_connect_status status) { #define MEI_CL_CS(status) case MEI_CL_CONN_##status: return #status @@ -770,8 +787,9 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) props_res = (struct hbm_props_response *)mei_msg; if (props_res->status) { - dev_err(&dev->pdev->dev, "hbm: properties response: wrong status = %d\n", - props_res->status); + dev_err(&dev->pdev->dev, "hbm: properties response: wrong status = %d %s\n", + props_res->status, + mei_hbm_status_str(props_res->status)); return -EPROTO; } diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h index 50526f92f092..6e31113b63df 100644 --- a/drivers/misc/mei/hw.h +++ b/drivers/misc/mei/hw.h @@ -97,23 +97,50 @@ enum mei_stop_reason_types { SYSTEM_S5_ENTRY = 0x08 }; + +/** + * mei_hbm_status - mei host bus messages return values + * + * @MEI_HBMS_SUCCESS - status success + * @MEI_HBMS_CLIENT_NOT_FOUND - client not found + * @MEI_HBMS_ALREADY_EXISTS - connection already established + * @MEI_HBMS_REJECTED - connection is rejected + * @MEI_HBMS_INVALID_PARAMETER - invalid parameter + * @MEI_HBMS_NOT_ALLOWED - operation not allowed + * @MEI_HBMS_ALREADY_STARTED - system is already started + * @MEI_HBMS_NOT_STARTED - system not started + */ +enum mei_hbm_status { + MEI_HBMS_SUCCESS = 0, + MEI_HBMS_CLIENT_NOT_FOUND = 1, + MEI_HBMS_ALREADY_EXISTS = 2, + MEI_HBMS_REJECTED = 3, + MEI_HBMS_INVALID_PARAMETER = 4, + MEI_HBMS_NOT_ALLOWED = 5, + MEI_HBMS_ALREADY_STARTED = 6, + MEI_HBMS_NOT_STARTED = 7, + + MEI_HBMS_MAX +}; + + /* * Client Connect Status * used by hbm_client_connect_response.status */ enum mei_cl_connect_status { - MEI_CL_CONN_SUCCESS = 0x00, - MEI_CL_CONN_NOT_FOUND = 0x01, - MEI_CL_CONN_ALREADY_STARTED = 0x02, - MEI_CL_CONN_OUT_OF_RESOURCES = 0x03, - MEI_CL_CONN_MESSAGE_SMALL = 0x04 + MEI_CL_CONN_SUCCESS = MEI_HBMS_SUCCESS, + MEI_CL_CONN_NOT_FOUND = MEI_HBMS_CLIENT_NOT_FOUND, + MEI_CL_CONN_ALREADY_STARTED = MEI_HBMS_ALREADY_EXISTS, + MEI_CL_CONN_OUT_OF_RESOURCES = MEI_HBMS_REJECTED, + MEI_CL_CONN_MESSAGE_SMALL = MEI_HBMS_INVALID_PARAMETER, }; /* * Client Disconnect Status */ enum mei_cl_disconnect_status { - MEI_CL_DISCONN_SUCCESS = 0x00 + MEI_CL_DISCONN_SUCCESS = MEI_HBMS_SUCCESS }; /* -- cgit v1.2.3 From 5a8373fba0ab2cec8d206747ad60ca4a30821a37 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 21 Aug 2014 14:29:17 +0300 Subject: mei: use disconnect name consistently Rename mei_cl_irq_close to mei_cl_irq_disconnect and MEI_FOP_CLOSE to MEI_FOP_DISCONNECT Remove unused MEI_FOP_OPEN Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 3 ++- drivers/misc/mei/interrupt.c | 8 ++++---- drivers/misc/mei/mei_dev.h | 6 ++---- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 1a4dafb77205..efac33929e53 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -516,7 +516,8 @@ int mei_cl_disconnect(struct mei_cl *cl) goto free; } - cb->fop_type = MEI_FOP_CLOSE; + cb->fop_type = MEI_FOP_DISCONNECT; + if (mei_hbuf_acquire(dev)) { if (mei_hbm_cl_disconnect_req(dev, cl)) { rets = -ENODEV; diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 19709b70874e..1b6c14b8642e 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -195,7 +195,7 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, /** - * mei_cl_irq_close - processes close related operation from + * mei_cl_irq_disconnect - processes close related operation from * interrupt thread context - send disconnect request * * @cl: client @@ -204,7 +204,7 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, * * returns 0, OK; otherwise, error. */ -static int mei_cl_irq_close(struct mei_cl *cl, struct mei_cl_cb *cb, +static int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) { struct mei_device *dev = cl->dev; @@ -495,9 +495,9 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) return -ENODEV; } switch (cb->fop_type) { - case MEI_FOP_CLOSE: + case MEI_FOP_DISCONNECT: /* send disconnect message */ - ret = mei_cl_irq_close(cl, cb, cmpl_list); + ret = mei_cl_irq_disconnect(cl, cb, cmpl_list); if (ret) return ret; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 9f684b9b3c93..0922ce867d47 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -132,17 +132,15 @@ enum mei_wd_states { * @MEI_FOP_READ - read * @MEI_FOP_WRITE - write * @MEI_FOP_CONNECT - connect + * @MEI_FOP_DISCONNECT - disconnect * @MEI_FOP_DISCONNECT_RSP - disconnect response - * @MEI_FOP_OPEN - open - * @MEI_FOP_CLOSE - close */ enum mei_cb_file_ops { MEI_FOP_READ = 0, MEI_FOP_WRITE, MEI_FOP_CONNECT, + MEI_FOP_DISCONNECT, MEI_FOP_DISCONNECT_RSP, - MEI_FOP_OPEN, - MEI_FOP_CLOSE }; /* -- cgit v1.2.3 From 12f45ed414c8d2eac1a98bf2deaf4117e8c0324f Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 21 Aug 2014 14:29:18 +0300 Subject: mei: revamp connect and disconnect response handling Both responses have same flow only the client status update is different. We introduce handler mei_hbm_cl_res() that handles both responses Also we use per client wait queue (cl->wait) rather then global dev->wait_recvd_msg Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 4 +- drivers/misc/mei/hbm.c | 118 +++++++++++++++++++++++++--------------------- 2 files changed, 65 insertions(+), 57 deletions(-) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index efac33929e53..449bb4564241 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -534,7 +534,7 @@ int mei_cl_disconnect(struct mei_cl *cl) } mutex_unlock(&dev->device_lock); - wait_event_timeout(dev->wait_recvd_msg, + wait_event_timeout(cl->wait, MEI_FILE_DISCONNECTED == cl->state, mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); @@ -639,7 +639,7 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file) } mutex_unlock(&dev->device_lock); - wait_event_timeout(dev->wait_recvd_msg, + wait_event_timeout(cl->wait, (cl->state == MEI_FILE_CONNECTED || cl->state == MEI_FILE_DISCONNECTED), mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index d50c8d1fb36d..cda914191a2f 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -495,39 +495,24 @@ int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl) } /** - * mei_hbm_cl_disconnect_res - disconnect response from ME + * mei_hbm_cl_disconnect_res - update the client state according + * disconnect response * - * @dev: the device structure - * @rs: disconnect response bus message + * @cl: mei host client + * @cmd: disconnect client response host bus message */ -static void mei_hbm_cl_disconnect_res(struct mei_device *dev, - struct hbm_client_connect_response *rs) +static void mei_hbm_cl_disconnect_res(struct mei_cl *cl, + struct mei_hbm_cl_cmd *cmd) { - struct mei_cl *cl; - struct mei_cl_cb *cb, *next; + struct hbm_client_connect_response *rs = + (struct hbm_client_connect_response *)cmd; - dev_dbg(&dev->pdev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n", + dev_dbg(&cl->dev->pdev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n", rs->me_addr, rs->host_addr, rs->status); - list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) { - cl = cb->cl; - - /* this should not happen */ - if (WARN_ON(!cl)) { - list_del(&cb->list); - return; - } - - if (mei_hbm_cl_addr_equal(cl, rs)) { - list_del(&cb->list); - if (rs->status == MEI_CL_DISCONN_SUCCESS) - cl->state = MEI_FILE_DISCONNECTED; - - cl->status = 0; - cl->timer_count = 0; - break; - } - } + if (rs->status == MEI_CL_DISCONN_SUCCESS) + cl->state = MEI_FILE_DISCONNECTED; + cl->status = 0; } /** @@ -545,24 +530,45 @@ int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl) } /** - * mei_hbm_cl_connect_res - connect response from the ME + * mei_hbm_cl_connect_res - update the client state according + * connection response * - * @dev: the device structure - * @rs: connect response bus message + * @cl: mei host client + * @cmd: connect client response host bus message */ -static void mei_hbm_cl_connect_res(struct mei_device *dev, - struct hbm_client_connect_response *rs) +static void mei_hbm_cl_connect_res(struct mei_cl *cl, + struct mei_hbm_cl_cmd *cmd) { + struct hbm_client_connect_response *rs = + (struct hbm_client_connect_response *)cmd; - struct mei_cl *cl; - struct mei_cl_cb *cb, *next; - - dev_dbg(&dev->pdev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n", + dev_dbg(&cl->dev->pdev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n", rs->me_addr, rs->host_addr, mei_cl_conn_status_str(rs->status)); - cl = NULL; + if (rs->status == MEI_CL_CONN_SUCCESS) + cl->state = MEI_FILE_CONNECTED; + else + cl->state = MEI_FILE_DISCONNECTED; + cl->status = mei_cl_conn_status_to_errno(rs->status); +} + +/** + * mei_hbm_cl_res - process hbm response received on behalf + * an client + * + * @dev: the device structure + * @rs: hbm client message + * @fop_type: file operation type + */ +static void mei_hbm_cl_res(struct mei_device *dev, + struct mei_hbm_cl_cmd *rs, + enum mei_cb_file_ops fop_type) +{ + struct mei_cl *cl; + struct mei_cl_cb *cb, *next; + cl = NULL; list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) { cl = cb->cl; @@ -572,7 +578,7 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev, continue; } - if (cb->fop_type != MEI_FOP_CONNECT) + if (cb->fop_type != fop_type) continue; if (mei_hbm_cl_addr_equal(cl, rs)) { @@ -584,12 +590,19 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev, if (!cl) return; + switch (fop_type) { + case MEI_FOP_CONNECT: + mei_hbm_cl_connect_res(cl, rs); + break; + case MEI_FOP_DISCONNECT: + mei_hbm_cl_disconnect_res(cl, rs); + break; + default: + return; + } + cl->timer_count = 0; - if (rs->status == MEI_CL_CONN_SUCCESS) - cl->state = MEI_FILE_CONNECTED; - else - cl->state = MEI_FILE_DISCONNECTED; - cl->status = mei_cl_conn_status_to_errno(rs->status); + wake_up(&cl->wait); } @@ -657,17 +670,18 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) { struct mei_bus_message *mei_msg; struct hbm_host_version_response *version_res; - struct hbm_client_connect_response *connect_res; - struct hbm_client_connect_response *disconnect_res; - struct hbm_client_connect_request *disconnect_req; - struct hbm_flow_control *flow_control; struct hbm_props_response *props_res; struct hbm_host_enum_response *enum_res; + struct mei_hbm_cl_cmd *cl_cmd; + struct hbm_client_connect_request *disconnect_req; + struct hbm_flow_control *flow_control; + /* read the message to our buffer */ BUG_ON(hdr->length >= sizeof(dev->rd_msg_buf)); mei_read_slots(dev, dev->rd_msg_buf, hdr->length); mei_msg = (struct mei_bus_message *)dev->rd_msg_buf; + cl_cmd = (struct mei_hbm_cl_cmd *)mei_msg; /* ignore spurious message and prevent reset nesting * hbm is put to idle during system reset @@ -730,18 +744,12 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) case CLIENT_CONNECT_RES_CMD: dev_dbg(&dev->pdev->dev, "hbm: client connect response: message received.\n"); - - connect_res = (struct hbm_client_connect_response *) mei_msg; - mei_hbm_cl_connect_res(dev, connect_res); - wake_up(&dev->wait_recvd_msg); + mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_CONNECT); break; case CLIENT_DISCONNECT_RES_CMD: dev_dbg(&dev->pdev->dev, "hbm: client disconnect response: message received.\n"); - - disconnect_res = (struct hbm_client_connect_response *) mei_msg; - mei_hbm_cl_disconnect_res(dev, disconnect_res); - wake_up(&dev->wait_recvd_msg); + mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_DISCONNECT); break; case MEI_FLOW_CONTROL_CMD: -- cgit v1.2.3 From cb02efc3a6e96a0dc4aba8ebf0c1136b72fbe8ba Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Thu, 21 Aug 2014 14:29:19 +0300 Subject: mei: wait for hbm start non-interruptible We cannot handle user interrupt in context of hbm start so we only wait for time out which is reasonably short. 1. Add kdoc 2. Rename state to better reflect its function 3. Simplify wait condition and rename wait_recvd_msg to wait_hbm_start Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hbm.c | 26 ++++++++++++++++---------- drivers/misc/mei/hbm.h | 6 ++++-- drivers/misc/mei/init.c | 2 +- drivers/misc/mei/mei_dev.h | 2 +- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index cda914191a2f..2968b52fc12a 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -172,21 +172,27 @@ bool mei_hbm_cl_addr_equal(struct mei_cl *cl, void *buf) cl->me_client_id == cmd->me_addr; } - +/** + * mei_hbm_start_wait - wait for start response message. + * + * @dev: the device structure + * + * returns 0 on success and < 0 on failure + */ int mei_hbm_start_wait(struct mei_device *dev) { int ret; - if (dev->hbm_state > MEI_HBM_START) + + if (dev->hbm_state > MEI_HBM_STARTING) return 0; mutex_unlock(&dev->device_lock); - ret = wait_event_interruptible_timeout(dev->wait_recvd_msg, - dev->hbm_state == MEI_HBM_IDLE || - dev->hbm_state >= MEI_HBM_STARTED, + ret = wait_event_timeout(dev->wait_hbm_start, + dev->hbm_state != MEI_HBM_STARTING, mei_secs_to_jiffies(MEI_HBM_TIMEOUT)); mutex_lock(&dev->device_lock); - if (ret <= 0 && (dev->hbm_state <= MEI_HBM_START)) { + if (ret == 0 && (dev->hbm_state <= MEI_HBM_STARTING)) { dev->hbm_state = MEI_HBM_IDLE; dev_err(&dev->pdev->dev, "waiting for mei start failed\n"); return -ETIME; @@ -227,7 +233,7 @@ int mei_hbm_start_req(struct mei_device *dev) return ret; } - dev->hbm_state = MEI_HBM_START; + dev->hbm_state = MEI_HBM_STARTING; dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; return 0; } @@ -726,7 +732,7 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) } if (dev->dev_state != MEI_DEV_INIT_CLIENTS || - dev->hbm_state != MEI_HBM_START) { + dev->hbm_state != MEI_HBM_STARTING) { dev_err(&dev->pdev->dev, "hbm: start: state mismatch, [%d, %d]\n", dev->dev_state, dev->hbm_state); return -EPROTO; @@ -739,7 +745,7 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) return -EIO; } - wake_up_interruptible(&dev->wait_recvd_msg); + wake_up(&dev->wait_hbm_start); break; case CLIENT_CONNECT_RES_CMD: @@ -866,7 +872,7 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) dev_dbg(&dev->pdev->dev, "hbm: stop request: message received\n"); dev->hbm_state = MEI_HBM_STOPPED; if (mei_hbm_stop_req(dev)) { - dev_err(&dev->pdev->dev, "hbm: start: failed to send stop request\n"); + dev_err(&dev->pdev->dev, "hbm: stop request: failed to send stop request\n"); return -EIO; } break; diff --git a/drivers/misc/mei/hbm.h b/drivers/misc/mei/hbm.h index 683eb2835cec..80920f096c04 100644 --- a/drivers/misc/mei/hbm.h +++ b/drivers/misc/mei/hbm.h @@ -25,13 +25,15 @@ struct mei_cl; * enum mei_hbm_state - host bus message protocol state * * @MEI_HBM_IDLE : protocol not started - * @MEI_HBM_START : start request message was sent + * @MEI_HBM_STARTING : start request message was sent + * @MEI_HBM_STARTED : start reply message was received * @MEI_HBM_ENUM_CLIENTS : enumeration request was sent * @MEI_HBM_CLIENT_PROPERTIES : acquiring clients properties + * @MEI_HBM_STOPPED : stopping exchange */ enum mei_hbm_state { MEI_HBM_IDLE = 0, - MEI_HBM_START, + MEI_HBM_STARTING, MEI_HBM_STARTED, MEI_HBM_ENUM_CLIENTS, MEI_HBM_CLIENT_PROPERTIES, diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 73ccbb65d4ff..9f635be684ea 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -360,7 +360,7 @@ void mei_device_init(struct mei_device *dev, const struct mei_cfg *cfg) mutex_init(&dev->device_lock); init_waitqueue_head(&dev->wait_hw_ready); init_waitqueue_head(&dev->wait_pg); - init_waitqueue_head(&dev->wait_recvd_msg); + init_waitqueue_head(&dev->wait_hbm_start); init_waitqueue_head(&dev->wait_stop_wd); dev->dev_state = MEI_DEV_INITIALIZING; dev->reset_count = 0; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 0922ce867d47..79124ae6a249 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -443,7 +443,7 @@ struct mei_device { */ wait_queue_head_t wait_hw_ready; wait_queue_head_t wait_pg; - wait_queue_head_t wait_recvd_msg; + wait_queue_head_t wait_hbm_start; wait_queue_head_t wait_stop_wd; /* -- cgit v1.2.3 From 2af89db1d61a872e5f2f1fb18d44cf5d8f5f6a2a Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 21 Aug 2014 14:29:20 +0300 Subject: mei: simplify handling of hbm client events Add mei_hbm_cl_find_by_cmd handler to retrieve the destination client Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hbm.c | 74 +++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 2968b52fc12a..280befc46d11 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -157,21 +157,42 @@ int mei_hbm_cl_write(struct mei_device *dev, } /** - * mei_hbm_cl_addr_equal - tells if they have the same address + * mei_hbm_cl_addr_equal - check if the client's and + * the message address match * - * @cl: - client - * @buf: buffer with cl header + * @cl: client + * @cmd: hbm client message * * returns true if addresses are the same */ static inline -bool mei_hbm_cl_addr_equal(struct mei_cl *cl, void *buf) +bool mei_hbm_cl_addr_equal(struct mei_cl *cl, struct mei_hbm_cl_cmd *cmd) { - struct mei_hbm_cl_cmd *cmd = buf; return cl->host_client_id == cmd->host_addr && cl->me_client_id == cmd->me_addr; } +/** + * mei_hbm_cl_find_by_cmd - find recipient client + * + * @dev: the device structure + * @buf: a buffer with hbm cl command + * + * returns the recipient client or NULL if not found + */ +static inline +struct mei_cl *mei_hbm_cl_find_by_cmd(struct mei_device *dev, void *buf) +{ + struct mei_hbm_cl_cmd *cmd = (struct mei_hbm_cl_cmd *)buf; + struct mei_cl *cl; + + list_for_each_entry(cl, &dev->file_list, link) + if (mei_hbm_cl_addr_equal(cl, cmd)) + return cl; + return NULL; +} + + /** * mei_hbm_start_wait - wait for start response message. * @@ -449,7 +470,7 @@ static int mei_hbm_add_single_flow_creds(struct mei_device *dev, * @flow_control: flow control response bus message */ static void mei_hbm_cl_flow_control_res(struct mei_device *dev, - struct hbm_flow_control *flow_control) + struct hbm_flow_control *flow_control) { struct mei_cl *cl; @@ -459,15 +480,11 @@ static void mei_hbm_cl_flow_control_res(struct mei_device *dev, return; } - /* normal connection */ - list_for_each_entry(cl, &dev->file_list, link) { - if (mei_hbm_cl_addr_equal(cl, flow_control)) { - cl->mei_flow_ctrl_creds++; - dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d creds %d.\n", - flow_control->host_addr, flow_control->me_addr, + cl = mei_hbm_cl_find_by_cmd(dev, flow_control); + if (cl) { + cl->mei_flow_ctrl_creds++; + cl_dbg(dev, cl, "flow control creds = %d.\n", cl->mei_flow_ctrl_creds); - break; - } } } @@ -627,23 +644,18 @@ static int mei_hbm_fw_disconnect_req(struct mei_device *dev, struct mei_cl *cl; struct mei_cl_cb *cb; - list_for_each_entry(cl, &dev->file_list, link) { - if (mei_hbm_cl_addr_equal(cl, disconnect_req)) { - dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n", - disconnect_req->host_addr, - disconnect_req->me_addr); - cl->state = MEI_FILE_DISCONNECTED; - cl->timer_count = 0; - - cb = mei_io_cb_init(cl, NULL); - if (!cb) - return -ENOMEM; - cb->fop_type = MEI_FOP_DISCONNECT_RSP; - cl_dbg(dev, cl, "add disconnect response as first\n"); - list_add(&cb->list, &dev->ctrl_wr_list.list); - - break; - } + cl = mei_hbm_cl_find_by_cmd(dev, disconnect_req); + if (cl) { + cl_dbg(dev, cl, "disconnect request received\n"); + cl->state = MEI_FILE_DISCONNECTED; + cl->timer_count = 0; + + cb = mei_io_cb_init(cl, NULL); + if (!cb) + return -ENOMEM; + cb->fop_type = MEI_FOP_DISCONNECT_RSP; + cl_dbg(dev, cl, "add disconnect response as first\n"); + list_add(&cb->list, &dev->ctrl_wr_list.list); } return 0; } -- cgit v1.2.3 From bae1cc7d41fd3048f55c21a6e59c35a3f0abaafe Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 21 Aug 2014 14:29:21 +0300 Subject: mei: extract supported features from the hbm version extract supported hbm features and commands from the hbm version Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hbm.c | 25 ++++++++++++++++++++++++- drivers/misc/mei/hw-me.c | 6 +----- drivers/misc/mei/mei_dev.h | 4 ++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 280befc46d11..9fc051b7f1a3 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -372,7 +372,8 @@ static int mei_hbm_prop_req(struct mei_device *dev) * @dev: the device structure * @pg_cmd: the pg command code * - * This function returns -EIO on write failure + * returns -EIO on write failure + * -EOPNOTSUPP if the operation is not supported by the protocol */ int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd) { @@ -381,6 +382,9 @@ int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd) const size_t len = sizeof(struct hbm_power_gate); int ret; + if (!dev->hbm_f_pg_supported) + return -EOPNOTSUPP; + mei_hbm_hdr(mei_hdr, len); req = (struct hbm_power_gate *)dev->wr_msg.data; @@ -660,6 +664,23 @@ static int mei_hbm_fw_disconnect_req(struct mei_device *dev, return 0; } +/** + * mei_hbm_config_features: check what hbm features and commands + * are supported by the fw + * + * @dev: the device structure + */ +static void mei_hbm_config_features(struct mei_device *dev) +{ + /* Power Gating Isolation Support */ + dev->hbm_f_pg_supported = 0; + if (dev->version.major_version > HBM_MAJOR_VERSION_PGI) + dev->hbm_f_pg_supported = 1; + + if (dev->version.major_version == HBM_MAJOR_VERSION_PGI && + dev->version.minor_version >= HBM_MINOR_VERSION_PGI) + dev->hbm_f_pg_supported = 1; +} /** * mei_hbm_version_is_supported - checks whether the driver can @@ -743,6 +764,8 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) break; } + mei_hbm_config_features(dev); + if (dev->dev_state != MEI_DEV_INIT_CLIENTS || dev->hbm_state != MEI_HBM_STARTING) { dev_err(&dev->pdev->dev, "hbm: start: state mismatch, [%d, %d]\n", diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index caf0da335994..498bd42bca25 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -574,11 +574,7 @@ static bool mei_me_pg_is_enabled(struct mei_device *dev) if ((reg & ME_PGIC_HRA) == 0) goto notsupported; - if (dev->version.major_version < HBM_MAJOR_VERSION_PGI) - goto notsupported; - - if (dev->version.major_version == HBM_MAJOR_VERSION_PGI && - dev->version.minor_version < HBM_MINOR_VERSION_PGI) + if (!dev->hbm_f_pg_supported) goto notsupported; return true; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 79124ae6a249..719edeeb3ceb 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -402,6 +402,9 @@ struct mei_cfg { * * @reset_count - limits the number of consecutive resets * @hbm_state - state of host bus message protocol + * + * @hbm_f_pg_supported - hbm feature pgi protocol + * * @pg_event - power gating event * @mem_addr - mem mapped base register address @@ -476,6 +479,7 @@ struct mei_device { } wr_msg; struct hbm_version version; + unsigned int hbm_f_pg_supported:1; struct list_head me_clients; DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); -- cgit v1.2.3 From 4f046e7b6f4f0d8c9504e22cf8eacfe5c78f0f01 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 21 Aug 2014 14:29:22 +0300 Subject: mei: enable adding more IOCTL handlers Handle ioctls in a switch statement so we can add more commands easily Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 53 ++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 957f44aaa97a..2f80c77629b0 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -523,8 +523,6 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) struct mei_connect_client_data *connect_data = NULL; int rets; - if (cmd != IOCTL_MEI_CONNECT_CLIENT) - return -EINVAL; if (WARN_ON(!cl || !cl->dev)) return -ENODEV; @@ -539,34 +537,39 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) goto out; } - dev_dbg(&dev->pdev->dev, ": IOCTL_MEI_CONNECT_CLIENT.\n"); - - connect_data = kzalloc(sizeof(struct mei_connect_client_data), + switch (cmd) { + case IOCTL_MEI_CONNECT_CLIENT: + dev_dbg(&dev->pdev->dev, ": IOCTL_MEI_CONNECT_CLIENT.\n"); + connect_data = kzalloc(sizeof(struct mei_connect_client_data), GFP_KERNEL); - if (!connect_data) { - rets = -ENOMEM; - goto out; - } - dev_dbg(&dev->pdev->dev, "copy connect data from user\n"); - if (copy_from_user(connect_data, (char __user *)data, - sizeof(struct mei_connect_client_data))) { - dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n"); - rets = -EFAULT; - goto out; - } + if (!connect_data) { + rets = -ENOMEM; + goto out; + } - rets = mei_ioctl_connect_client(file, connect_data); + if (copy_from_user(connect_data, (char __user *)data, + sizeof(struct mei_connect_client_data))) { + dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n"); + rets = -EFAULT; + goto out; + } - /* if all is ok, copying the data back to user. */ - if (rets) - goto out; + rets = mei_ioctl_connect_client(file, connect_data); + if (rets) + goto out; - dev_dbg(&dev->pdev->dev, "copy connect data to user\n"); - if (copy_to_user((char __user *)data, connect_data, + /* if all is ok, copying the data back to user. */ + if (copy_to_user((char __user *)data, connect_data, sizeof(struct mei_connect_client_data))) { - dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n"); - rets = -EFAULT; - goto out; + dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n"); + rets = -EFAULT; + goto out; + } + + break; + default: + dev_err(&dev->pdev->dev, ": unsupported ioctl %d.\n", cmd); + rets = -ENOIOCTLCMD; } out: -- cgit v1.2.3 From 154eb18fedd5219516887a7e2bf2825b1b06ff2b Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 21 Aug 2014 14:29:23 +0300 Subject: mei: use connect_data on the stack There is no need for dynamic allocation for connect_data. We can use variable on the stack and make code less error prone and simple Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 2f80c77629b0..d60621ef5621 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -433,9 +433,6 @@ static int mei_ioctl_connect_client(struct file *file, int rets; cl = file->private_data; - if (WARN_ON(!cl || !cl->dev)) - return -ENODEV; - dev = cl->dev; if (dev->dev_state != MEI_DEV_ENABLED) { @@ -506,7 +503,6 @@ end: return rets; } - /** * mei_ioctl - the IOCTL function * @@ -520,7 +516,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) { struct mei_device *dev; struct mei_cl *cl = file->private_data; - struct mei_connect_client_data *connect_data = NULL; + struct mei_connect_client_data connect_data; int rets; @@ -540,26 +536,19 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) switch (cmd) { case IOCTL_MEI_CONNECT_CLIENT: dev_dbg(&dev->pdev->dev, ": IOCTL_MEI_CONNECT_CLIENT.\n"); - connect_data = kzalloc(sizeof(struct mei_connect_client_data), - GFP_KERNEL); - if (!connect_data) { - rets = -ENOMEM; - goto out; - } - - if (copy_from_user(connect_data, (char __user *)data, + if (copy_from_user(&connect_data, (char __user *)data, sizeof(struct mei_connect_client_data))) { dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n"); rets = -EFAULT; goto out; } - rets = mei_ioctl_connect_client(file, connect_data); + rets = mei_ioctl_connect_client(file, &connect_data); if (rets) goto out; /* if all is ok, copying the data back to user. */ - if (copy_to_user((char __user *)data, connect_data, + if (copy_to_user((char __user *)data, &connect_data, sizeof(struct mei_connect_client_data))) { dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n"); rets = -EFAULT; @@ -567,13 +556,13 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) } break; + default: dev_err(&dev->pdev->dev, ": unsupported ioctl %d.\n", cmd); rets = -ENOIOCTLCMD; } out: - kfree(connect_data); mutex_unlock(&dev->device_lock); return rets; } -- cgit v1.2.3 From cfda2794b5afe7ce64ee9605c64bef0e56a48125 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Mon, 25 Aug 2014 16:46:53 +0300 Subject: mei: bus: fix possible boundaries violation function 'strncpy' will fill whole buffer 'id.name' of fixed size (32) with string value and will not leave place for NULL-terminator. Possible buffer boundaries violation in following string operations. Replace strncpy with strlcpy. Cc: stable@vger.kernel.org # 3.10+ Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 09dad2df7aae..1cf3a72f2954 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -70,7 +70,7 @@ static int mei_cl_device_probe(struct device *dev) dev_dbg(dev, "Device probe\n"); - strncpy(id.name, dev_name(dev), sizeof(id.name)); + strlcpy(id.name, dev_name(dev), sizeof(id.name)); return driver->probe(device, &id); } -- cgit v1.2.3 From 1698da246134e88bb05550dafe7c34b47387655a Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Sat, 2 Aug 2014 00:34:23 +0530 Subject: EEPROM: Introduce the use of devm_kzalloc This patch introduces the use of devm_kzalloc and does away with the kfrees in the probe and remove functions. Also, a label and the err variable are removed. The header device.h is included to make the devm_ function explicitly available and slab.h is done away with as it is no longer needed. Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Reviewed-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/misc/eeprom/eeprom.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/drivers/misc/eeprom/eeprom.c b/drivers/misc/eeprom/eeprom.c index 33f8673d23a6..b432873def96 100644 --- a/drivers/misc/eeprom/eeprom.c +++ b/drivers/misc/eeprom/eeprom.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include @@ -159,12 +159,11 @@ static int eeprom_probe(struct i2c_client *client, { struct i2c_adapter *adapter = client->adapter; struct eeprom_data *data; - int err; - if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct eeprom_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; memset(data->data, 0xff, EEPROM_SIZE); i2c_set_clientdata(client, data); @@ -190,22 +189,12 @@ static int eeprom_probe(struct i2c_client *client, } /* create the sysfs eeprom file */ - err = sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr); - if (err) - goto exit_kfree; - - return 0; - -exit_kfree: - kfree(data); -exit: - return err; + return sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr); } static int eeprom_remove(struct i2c_client *client) { sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr); - kfree(i2c_get_clientdata(client)); return 0; } -- cgit v1.2.3 From 322d3f6a58e479d27b86deb6024148669d6a2fa1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 6 Aug 2014 17:37:41 +0200 Subject: misc: lattice-ecp3-config: Add missing MODULE_FIRMWARE() Signed-off-by: Takashi Iwai Tested-by: Jean-Michel Hautbois Signed-off-by: Greg Kroah-Hartman --- drivers/misc/lattice-ecp3-config.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/misc/lattice-ecp3-config.c b/drivers/misc/lattice-ecp3-config.c index 7e1efd5f58f0..c544f1f50f52 100644 --- a/drivers/misc/lattice-ecp3-config.c +++ b/drivers/misc/lattice-ecp3-config.c @@ -247,3 +247,4 @@ module_spi_driver(lattice_ecp3_driver); MODULE_AUTHOR("Stefan Roese "); MODULE_DESCRIPTION("Lattice ECP3 FPGA configuration via SPI"); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(FIRMWARE_NAME); -- cgit v1.2.3 From 759e7d6df3e4da96573a0bf957383211314792ee Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Thu, 7 Aug 2014 17:43:28 +0530 Subject: pcie-gadget-spear: use devm_ functions The various devm_ functions allocate memory that is released when a driver detaches. This patch uses these functions for data that is allocated in the probe function of a platform device and is only freed in the remove function. Also, the unnecessary labels are removed and linux/device.h is added to make sure the devm_*() routine declarations are unambiguously available. The initial call to platform_get_resource is moved down to the introduced call to devm_ioremap_resource that uses its result. Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/misc/spear13xx_pcie_gadget.c | 98 +++++++++--------------------------- 1 file changed, 23 insertions(+), 75 deletions(-) diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c index 2e13614d41e8..fe3ad0ca9a3e 100644 --- a/drivers/misc/spear13xx_pcie_gadget.c +++ b/drivers/misc/spear13xx_pcie_gadget.c @@ -9,6 +9,7 @@ * warranty of any kind, whether express or implied. */ +#include #include #include #include @@ -743,58 +744,33 @@ static int spear_pcie_gadget_probe(struct platform_device *pdev) struct config_item *cg_item; struct configfs_subsystem *subsys; - /* get resource for application registers*/ - - res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res0) { - dev_err(&pdev->dev, "no resource defined\n"); - return -EBUSY; - } - if (!request_mem_region(res0->start, resource_size(res0), - pdev->name)) { - dev_err(&pdev->dev, "pcie gadget region already claimed\n"); - return -EBUSY; - } - /* get resource for dbi registers*/ - - res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!res1) { - dev_err(&pdev->dev, "no resource defined\n"); - goto err_rel_res0; - } - if (!request_mem_region(res1->start, resource_size(res1), - pdev->name)) { - dev_err(&pdev->dev, "pcie gadget region already claimed\n"); - goto err_rel_res0; - } - - target = kzalloc(sizeof(*target), GFP_KERNEL); + target = devm_kzalloc(&pdev->dev, sizeof(*target), GFP_KERNEL); if (!target) { dev_err(&pdev->dev, "out of memory\n"); - status = -ENOMEM; - goto err_rel_res; + return -ENOMEM; } cg_item = &target->subsys.su_group.cg_item; sprintf(cg_item->ci_namebuf, "pcie_gadget.%d", pdev->id); cg_item->ci_type = &pcie_gadget_target_type; config = &target->config; - config->va_app_base = (void __iomem *)ioremap(res0->start, - resource_size(res0)); - if (!config->va_app_base) { + + /* get resource for application registers*/ + res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); + config->va_app_base = devm_ioremap_resource(&pdev->dev, res0); + if (IS_ERR(config->va_app_base)) { dev_err(&pdev->dev, "ioremap fail\n"); - status = -ENOMEM; - goto err_kzalloc; + return PTR_ERR(config->va_app_base); } + /* get resource for dbi registers*/ + res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); config->base = (void __iomem *)res1->start; - config->va_dbi_base = (void __iomem *)ioremap(res1->start, - resource_size(res1)); - if (!config->va_dbi_base) { + config->va_dbi_base = devm_ioremap_resource(&pdev->dev, res1); + if (IS_ERR(config->va_dbi_base)) { dev_err(&pdev->dev, "ioremap fail\n"); - status = -ENOMEM; - goto err_iounmap_app; + return PTR_ERR(config->va_dbi_base); } platform_set_drvdata(pdev, target); @@ -802,15 +778,15 @@ static int spear_pcie_gadget_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "no update irq?\n"); - status = irq; - goto err_iounmap; + return irq; } - status = request_irq(irq, spear_pcie_gadget_irq, 0, pdev->name, NULL); + status = devm_request_irq(&pdev->dev, irq, spear_pcie_gadget_irq, + 0, pdev->name, NULL); if (status) { dev_err(&pdev->dev, "pcie gadget interrupt IRQ%d already claimed\n", irq); - goto err_iounmap; + return status; } /* Register configfs hooks */ @@ -819,7 +795,7 @@ static int spear_pcie_gadget_probe(struct platform_device *pdev) mutex_init(&subsys->su_mutex); status = configfs_register_subsystem(subsys); if (status) - goto err_irq; + return status; /* * init basic pcie application registers @@ -835,13 +811,12 @@ static int spear_pcie_gadget_probe(struct platform_device *pdev) clk = clk_get_sys("pcie1", NULL); if (IS_ERR(clk)) { pr_err("%s:couldn't get clk for pcie1\n", __func__); - status = PTR_ERR(clk); - goto err_irq; + return PTR_ERR(clk); } status = clk_enable(clk); if (status) { pr_err("%s:couldn't enable clk for pcie1\n", __func__); - goto err_irq; + return status; } } else if (pdev->id == 2) { /* @@ -851,53 +826,26 @@ static int spear_pcie_gadget_probe(struct platform_device *pdev) clk = clk_get_sys("pcie2", NULL); if (IS_ERR(clk)) { pr_err("%s:couldn't get clk for pcie2\n", __func__); - status = PTR_ERR(clk); - goto err_irq; + return PTR_ERR(clk); } status = clk_enable(clk); if (status) { pr_err("%s:couldn't enable clk for pcie2\n", __func__); - goto err_irq; + return status; } } spear13xx_pcie_device_init(config); return 0; -err_irq: - free_irq(irq, NULL); -err_iounmap: - iounmap(config->va_dbi_base); -err_iounmap_app: - iounmap(config->va_app_base); -err_kzalloc: - kfree(target); -err_rel_res: - release_mem_region(res1->start, resource_size(res1)); -err_rel_res0: - release_mem_region(res0->start, resource_size(res0)); - return status; } static int spear_pcie_gadget_remove(struct platform_device *pdev) { - struct resource *res0, *res1; static struct pcie_gadget_target *target; - struct spear_pcie_gadget_config *config; - int irq; - res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); - res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); - irq = platform_get_irq(pdev, 0); target = platform_get_drvdata(pdev); - config = &target->config; - free_irq(irq, NULL); - iounmap(config->va_dbi_base); - iounmap(config->va_app_base); - release_mem_region(res1->start, resource_size(res1)); - release_mem_region(res0->start, resource_size(res0)); configfs_unregister_subsystem(&target->subsys); - kfree(target); return 0; } -- cgit v1.2.3 From 5534b6733d202b72e3e78be4e9b601b57120d1e3 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 13 Aug 2014 14:02:05 +0200 Subject: char: xilinx_hwicap: Remove .owner field for driver There is no need to init .owner field. Based on the patch from Peter Griffin "mmc: remove .owner field for drivers using module_platform_driver" This patch removes the superflous .owner field for drivers which use the module_platform_driver API, as this is overriden in platform_driver_register anyway." Signed-off-by: Michal Simek Signed-off-by: Greg Kroah-Hartman --- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 9b1a5ac4881d..c07dfe5c4da3 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -843,7 +843,6 @@ static struct platform_driver hwicap_platform_driver = { .probe = hwicap_drv_probe, .remove = hwicap_drv_remove, .driver = { - .owner = THIS_MODULE, .name = DRIVER_NAME, .of_match_table = hwicap_of_match, }, -- cgit v1.2.3 From 95ead5f606971022b6b72557038eef6a78c86e59 Mon Sep 17 00:00:00 2001 From: Eli Billauer Date: Sun, 17 Aug 2014 18:01:03 +0300 Subject: documentation: devicetree: Added xillybus to vendor-prefixes Signed-off-by: Eli Billauer Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index ac7269f90764..06e698ab99e6 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -147,6 +147,7 @@ winbond Winbond Electronics corp. wlf Wolfson Microelectronics wm Wondermedia Technologies, Inc. xes Extreme Engineering Solutions (X-ES) +xillybus Xillybus Ltd. xlnx Xilinx zyxel ZyXEL Communications Corp. zarlink Zarlink Semiconductor -- cgit v1.2.3 From e0b04f2e94baca0f8135e7d5648c21be2e29d831 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Fri, 22 Aug 2014 14:09:23 +0200 Subject: drivers/ipack/devices/ipoctal.h: Fix typo in include guard Signed-off-by: Rasmus Villemoes Acked-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/ipack/devices/ipoctal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ipack/devices/ipoctal.h b/drivers/ipack/devices/ipoctal.h index 28f1c4233154..7fede0eb6a0c 100644 --- a/drivers/ipack/devices/ipoctal.h +++ b/drivers/ipack/devices/ipoctal.h @@ -12,7 +12,7 @@ * Software Foundation; version 2 of the License. */ -#ifndef _IPOCTAL_H +#ifndef _IPOCTAL_H_ #define _IPOCTAL_H_ #define NR_CHANNELS 8 -- cgit v1.2.3 From 78f22bc29e6e367f272a7fc700baa4d4263d376a Mon Sep 17 00:00:00 2001 From: Federico Vaga Date: Tue, 2 Sep 2014 17:31:39 +0200 Subject: ipoctal: reset function istead of duplicate code Signed-off-by: Federico Vaga Acked-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/ipack/devices/ipoctal.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index e41bef048c23..a1514a79e487 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -55,6 +55,16 @@ struct ipoctal { u8 __iomem *int_space; }; +static void ipoctal_reset_channel(struct ipoctal_channel *channel) +{ + iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); + channel->rx_enable = 0; + iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr); +} + static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) { struct ipoctal_channel *channel; @@ -304,10 +314,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_A; } - iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); - channel->rx_enable = 0; - iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); + ipoctal_reset_channel(channel); iowrite8(MR1_CHRL_8_BITS | MR1_ERROR_CHAR | MR1_RxINT_RxRDY, &channel->regs->w.mr); /* mr1 */ iowrite8(0, &channel->regs->w.mr); /* mr2 */ @@ -467,11 +474,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, cflag = tty->termios.c_cflag; /* Disable and reset everything before change the setup */ - iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr); + ipoctal_reset_channel(channel); /* Set Bits per chars */ switch (cflag & CSIZE) { @@ -609,12 +612,7 @@ static void ipoctal_hangup(struct tty_struct *tty) tty_port_hangup(&channel->tty_port); - iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); - channel->rx_enable = 0; - iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr); + ipoctal_reset_channel(channel); clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags); wake_up_interruptible(&channel->tty_port.open_wait); @@ -627,12 +625,7 @@ static void ipoctal_shutdown(struct tty_struct *tty) if (channel == NULL) return; - iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); - channel->rx_enable = 0; - iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr); + ipoctal_reset_channel(channel); clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags); } -- cgit v1.2.3 From 36c53b3cc3fac6952af68f43609b15ae050c9318 Mon Sep 17 00:00:00 2001 From: Federico Vaga Date: Tue, 2 Sep 2014 17:31:40 +0200 Subject: ipack: save carrier owner to allow device to get it There was not any kind of protection against carrier driver removal. In this way, device driver can 'get' the carrier driver when it is using it. Signed-off-by: Federico Vaga Acked-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/ipack/carriers/tpci200.c | 3 ++- drivers/ipack/ipack.c | 4 +++- include/linux/ipack.h | 24 +++++++++++++++++++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/ipack/carriers/tpci200.c b/drivers/ipack/carriers/tpci200.c index de5e32151a1e..9b23843dcad4 100644 --- a/drivers/ipack/carriers/tpci200.c +++ b/drivers/ipack/carriers/tpci200.c @@ -572,7 +572,8 @@ static int tpci200_pci_probe(struct pci_dev *pdev, /* Register the carrier in the industry pack bus driver */ tpci200->info->ipack_bus = ipack_bus_register(&pdev->dev, TPCI200_NB_SLOT, - &tpci200_bus_ops); + &tpci200_bus_ops, + THIS_MODULE); if (!tpci200->info->ipack_bus) { dev_err(&pdev->dev, "error registering the carrier on ipack driver\n"); diff --git a/drivers/ipack/ipack.c b/drivers/ipack/ipack.c index d0016ba469ed..c0e7b624ce54 100644 --- a/drivers/ipack/ipack.c +++ b/drivers/ipack/ipack.c @@ -206,7 +206,8 @@ static struct bus_type ipack_bus_type = { }; struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, - const struct ipack_bus_ops *ops) + const struct ipack_bus_ops *ops, + struct module *owner) { int bus_nr; struct ipack_bus_device *bus; @@ -225,6 +226,7 @@ struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, bus->parent = parent; bus->slots = slots; bus->ops = ops; + bus->owner = owner; return bus; } EXPORT_SYMBOL_GPL(ipack_bus_register); diff --git a/include/linux/ipack.h b/include/linux/ipack.h index 1888e06ddf64..8bddc3fbdddf 100644 --- a/include/linux/ipack.h +++ b/include/linux/ipack.h @@ -172,6 +172,7 @@ struct ipack_bus_ops { * @ops: bus operations for the mezzanine drivers */ struct ipack_bus_device { + struct module *owner; struct device *parent; int slots; int bus_nr; @@ -189,7 +190,8 @@ struct ipack_bus_device { * available bus device in ipack. */ struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, - const struct ipack_bus_ops *ops); + const struct ipack_bus_ops *ops, + struct module *owner); /** * ipack_bus_unregister -- unregister an ipack bus @@ -265,3 +267,23 @@ void ipack_put_device(struct ipack_device *dev); .format = (_format), \ .vendor = (vend), \ .device = (dev) + +/** + * ipack_get_carrier - it increase the carrier ref. counter of + * the carrier module + * @dev: mezzanine device which wants to get the carrier + */ +static inline int ipack_get_carrier(struct ipack_device *dev) +{ + return try_module_get(dev->bus->owner); +} + +/** + * ipack_get_carrier - it decrease the carrier ref. counter of + * the carrier module + * @dev: mezzanine device which wants to get the carrier + */ +static inline void ipack_put_carrier(struct ipack_device *dev) +{ + module_put(dev->bus->owner); +} -- cgit v1.2.3 From 82a82340bab6c251e0705339f60763718eaa2a22 Mon Sep 17 00:00:00 2001 From: Federico Vaga Date: Tue, 2 Sep 2014 17:31:41 +0200 Subject: ipoctal: get carrier driver to avoid rmmod Signed-off-by: Federico Vaga Acked-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/ipack/devices/ipoctal.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index a1514a79e487..42700815d05f 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -55,6 +55,12 @@ struct ipoctal { u8 __iomem *int_space; }; +static inline struct ipoctal *chan_to_ipoctal(struct ipoctal_channel *chan, + unsigned int index) +{ + return container_of(chan, struct ipoctal, channel[index]); +} + static void ipoctal_reset_channel(struct ipoctal_channel *channel) { iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); @@ -82,12 +88,20 @@ static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) static int ipoctal_open(struct tty_struct *tty, struct file *file) { - struct ipoctal_channel *channel; + struct ipoctal_channel *channel = dev_get_drvdata(tty->dev); + struct ipoctal *ipoctal = chan_to_ipoctal(channel, tty->index); + int err; - channel = dev_get_drvdata(tty->dev); tty->driver_data = channel; - return tty_port_open(&channel->tty_port, tty, file); + if (!ipack_get_carrier(ipoctal->dev)) + return -EBUSY; + + err = tty_port_open(&channel->tty_port, tty, file); + if (err) + ipack_put_carrier(ipoctal->dev); + + return err; } static void ipoctal_reset_stats(struct ipoctal_stats *stats) @@ -629,6 +643,15 @@ static void ipoctal_shutdown(struct tty_struct *tty) clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags); } +static void ipoctal_cleanup(struct tty_struct *tty) +{ + struct ipoctal_channel *channel = tty->driver_data; + struct ipoctal *ipoctal = chan_to_ipoctal(channel, tty->index); + + /* release the carrier driver */ + ipack_put_carrier(ipoctal->dev); +} + static const struct tty_operations ipoctal_fops = { .ioctl = NULL, .open = ipoctal_open, @@ -640,6 +663,7 @@ static const struct tty_operations ipoctal_fops = { .get_icount = ipoctal_get_icount, .hangup = ipoctal_hangup, .shutdown = ipoctal_shutdown, + .cleanup = ipoctal_cleanup, }; static int ipoctal_probe(struct ipack_device *dev) -- cgit v1.2.3 From 17891c8a9ea17a11b437c7184f7f04e0ab7be811 Mon Sep 17 00:00:00 2001 From: "Matwey V. Kornilov" Date: Wed, 27 Aug 2014 12:07:43 +0400 Subject: parport: parport_pc: Introduce intel_bug_present function. Put the code to check present of the Intel bug from parport_EPP_supported into new intel_bug_present function. The later also return ECR register to the state it has before function call. Signed-off-by: Matwey V. Kornilov Signed-off-by: Greg Kroah-Hartman --- drivers/parport/parport_pc.c | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 76ee7750bc5e..fedc06bed18d 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -1702,6 +1702,30 @@ static int parport_ECP_supported(struct parport *pb) } #endif +static int intel_bug_present(struct parport *pb) +{ + const struct parport_pc_private *priv = pb->private_data; + int bug_present = 0; + + if (priv->ecr) { + /* store value of ECR */ + unsigned char ecr = inb(ECONTROL(pb)); + unsigned char i; + for (i = 0x00; i < 0x80; i += 0x20) { + ECR_WRITE(pb, i); + if (clear_epp_timeout(pb)) { + /* Phony EPP in ECP. */ + bug_present = 1; + break; + } + } + /* return ECR into the inital state */ + ECR_WRITE(pb, ecr); + } + + return bug_present; +} + static int parport_ECPPS2_supported(struct parport *pb) { const struct parport_pc_private *priv = pb->private_data; @@ -1722,8 +1746,6 @@ static int parport_ECPPS2_supported(struct parport *pb) static int parport_EPP_supported(struct parport *pb) { - const struct parport_pc_private *priv = pb->private_data; - /* * Theory: * Bit 0 of STR is the EPP timeout bit, this bit is 0 @@ -1742,16 +1764,8 @@ static int parport_EPP_supported(struct parport *pb) return 0; /* No way to clear timeout */ /* Check for Intel bug. */ - if (priv->ecr) { - unsigned char i; - for (i = 0x00; i < 0x80; i += 0x20) { - ECR_WRITE(pb, i); - if (clear_epp_timeout(pb)) { - /* Phony EPP in ECP. */ - return 0; - } - } - } + if (intel_bug_present(pb)) + return 0; pb->modes |= PARPORT_MODE_EPP; -- cgit v1.2.3 From 0ae39cc98192252f756f8943be85e9f4dbd8436e Mon Sep 17 00:00:00 2001 From: "Matwey V. Kornilov" Date: Wed, 27 Aug 2014 12:07:44 +0400 Subject: parport: parport_pc: Implement architecture and device check to cut off false-positives We definitely know that only x86 (32-bit) architecture is affected by the issue, so implement a stub instead of the actual check for other architectures. We also know that motherboard LPT chipset is affected, so the port is either come from parport_pc_init (when `io' module param is used) or parport_pc_find_isa_ports (when default LPT ports are probbed: 0x378, 0x278, 0x3bc). In both cases the port considered as 'legacy' and `dev' member of struct parport is NULL. See also comments for `struct parport' in parport.h Signed-off-by: Matwey V. Kornilov Signed-off-by: Greg Kroah-Hartman --- drivers/parport/parport_pc.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index fedc06bed18d..f721299eb1ba 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -1702,7 +1702,8 @@ static int parport_ECP_supported(struct parport *pb) } #endif -static int intel_bug_present(struct parport *pb) +#ifdef CONFIG_X86_32 +static int intel_bug_present_check_epp(struct parport *pb) { const struct parport_pc_private *priv = pb->private_data; int bug_present = 0; @@ -1725,6 +1726,21 @@ static int intel_bug_present(struct parport *pb) return bug_present; } +static int intel_bug_present(struct parport *pb) +{ +/* Check whether the device is legacy, not PCI or PCMCIA. Only legacy is known to be affected. */ + if (pb->dev != NULL) { + return 0; + } + + return intel_bug_present_check_epp(pb); +} +#else +static int intel_bug_present(struct parport *pb) +{ + return 0; +} +#endif /* CONFIG_X86_32 */ static int parport_ECPPS2_supported(struct parport *pb) { -- cgit v1.2.3 From e4ebe5fe2d507a4c228bf90dea7dd4de57cbce92 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 28 Aug 2014 14:14:08 +0100 Subject: misc: st_core: Protect unsigned value against becoming negative Coverity reported: This less-than-zero comparison of an unsigned value is never true. In answer to that, we only ever decrement if protos_registered is positive. We can subsequently remove the paranoid checking during unregister. Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 1972d57aadb3..54be83d3efdd 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -153,8 +153,9 @@ static void st_reg_complete(struct st_data_s *st_gdata, char err) (st_gdata->list[i]->priv_data, err); pr_info("protocol %d's cb sent %d\n", i, err); if (err) { /* cleanup registered protocol */ - st_gdata->protos_registered--; st_gdata->is_registered[i] = false; + if (st_gdata->protos_registered) + st_gdata->protos_registered--; } } } @@ -639,14 +640,12 @@ long st_unregister(struct st_proto_s *proto) return -EPROTONOSUPPORT; } - st_gdata->protos_registered--; + if (st_gdata->protos_registered) + st_gdata->protos_registered--; + remove_channel_from_table(st_gdata, proto); spin_unlock_irqrestore(&st_gdata->lock, flags); - /* paranoid check */ - if (st_gdata->protos_registered < ST_EMPTY) - st_gdata->protos_registered = ST_EMPTY; - if ((st_gdata->protos_registered == ST_EMPTY) && (!test_bit(ST_REG_PENDING, &st_gdata->st_state))) { pr_info(" all chnl_ids unregistered "); -- cgit v1.2.3 From ffdbb715fa0c53203b1ea2a6ecc54bdcc8951612 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Thu, 28 Aug 2014 14:14:09 +0100 Subject: misc: st_kim: Increase size of dev_name buffer to incorporate termination Calling strncpy with a maximum size argument of 32 bytes on destination array kim_gdata->dev_name of size 32 bytes might leave the destination string unterminated. Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman --- include/linux/ti_wilink_st.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/ti_wilink_st.h b/include/linux/ti_wilink_st.h index 932b76392248..884d6263e962 100644 --- a/include/linux/ti_wilink_st.h +++ b/include/linux/ti_wilink_st.h @@ -268,7 +268,7 @@ struct kim_data_s { struct st_data_s *core_data; struct chip_version version; unsigned char ldisc_install; - unsigned char dev_name[UART_DEV_NAME_LEN]; + unsigned char dev_name[UART_DEV_NAME_LEN + 1]; unsigned char flow_cntrl; unsigned long baud_rate; }; -- cgit v1.2.3 From 95a8825c9c3482e31ee5064184138a18be186515 Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Wed, 10 Sep 2014 16:37:46 +0200 Subject: GenWQE: Check pci_get_totalvfs return code Currently the driver is using the pci_get_totalvfs() return code directly in a loop. To avoid problems with potentially negative returns in case of errors, we are adding some more sanity checking code. Signed-off-by: Frank Haverkamp Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_base.c | 9 ++++++++- drivers/misc/genwqe/card_base.h | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index 43bbabc96b6c..070a55c36101 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -346,8 +346,13 @@ static bool genwqe_setup_vf_jtimer(struct genwqe_dev *cd) unsigned int vf; u32 T = genwqe_T_psec(cd); u64 x; + int totalvfs; - for (vf = 0; vf < pci_sriov_get_totalvfs(pci_dev); vf++) { + totalvfs = pci_sriov_get_totalvfs(pci_dev); + if (totalvfs <= 0) + return false; + + for (vf = 0; vf < totalvfs; vf++) { if (cd->vf_jobtimeout_msec[vf] == 0) continue; @@ -1125,6 +1130,8 @@ static int genwqe_pci_setup(struct genwqe_dev *cd) } cd->num_vfs = pci_sriov_get_totalvfs(pci_dev); + if (cd->num_vfs < 0) + cd->num_vfs = 0; err = genwqe_read_ids(cd); if (err) diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h index 67abd8cb2247..37657d6228de 100644 --- a/drivers/misc/genwqe/card_base.h +++ b/drivers/misc/genwqe/card_base.h @@ -306,7 +306,7 @@ struct genwqe_dev { struct pci_dev *pci_dev; /* PCI device */ void __iomem *mmio; /* BAR-0 MMIO start */ unsigned long mmio_len; - u16 num_vfs; + int num_vfs; u32 vf_jobtimeout_msec[GENWQE_MAX_VFS]; int is_privileged; /* access to all regs possible */ -- cgit v1.2.3 From 64df2ec5108de3f627761cade7b31e5d583ce448 Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Wed, 10 Sep 2014 16:37:47 +0200 Subject: GenWQE: Remove sysfs entry for driver version A special sysfs entry to display the driver version is not needed. We left the driver version and adjusted it to the naming a lot of other drivers use. The information can be retrieved by using modinfo genwqe_card. modinfo genwqe_card will provide the same information. Signed-off-by: Frank Haverkamp Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_base.c | 2 +- drivers/misc/genwqe/card_ddcb.c | 2 +- drivers/misc/genwqe/card_debugfs.c | 2 +- drivers/misc/genwqe/card_sysfs.c | 9 --------- drivers/misc/genwqe/genwqe_driver.h | 2 +- 5 files changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index 070a55c36101..c60ad4bd7ed6 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -48,7 +48,7 @@ MODULE_AUTHOR("Joerg-Stephan Vogt "); MODULE_AUTHOR("Michal Jung "); MODULE_DESCRIPTION("GenWQE Card"); -MODULE_VERSION(DRV_VERS_STRING); +MODULE_VERSION(DRV_VERSION); MODULE_LICENSE("GPL"); static char genwqe_driver_name[] = GENWQE_DEVNAME; diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c index dc9851a5540e..1102e1ef8104 100644 --- a/drivers/misc/genwqe/card_ddcb.c +++ b/drivers/misc/genwqe/card_ddcb.c @@ -740,7 +740,7 @@ int genwqe_init_debug_data(struct genwqe_dev *cd, struct genwqe_debug_data *d) } len = sizeof(d->driver_version); - snprintf(d->driver_version, len, "%s", DRV_VERS_STRING); + snprintf(d->driver_version, len, "%s", DRV_VERSION); d->slu_unitcfg = cd->slu_unitcfg; d->app_unitcfg = cd->app_unitcfg; return 0; diff --git a/drivers/misc/genwqe/card_debugfs.c b/drivers/misc/genwqe/card_debugfs.c index c9b4d6d0eb99..170a7915497c 100644 --- a/drivers/misc/genwqe/card_debugfs.c +++ b/drivers/misc/genwqe/card_debugfs.c @@ -323,7 +323,7 @@ static int genwqe_info_show(struct seq_file *s, void *unused) " Base Clock : %u MHz\n" " Arch/SVN Release: %u/%llx\n" " Bitstream : %llx\n", - GENWQE_DEVNAME, DRV_VERS_STRING, dev_name(&pci_dev->dev), + GENWQE_DEVNAME, DRV_VERSION, dev_name(&pci_dev->dev), genwqe_is_privileged(cd) ? "Physical" : "Virtual or no SR-IOV", cd->card_idx, slu_id, app_id, diff --git a/drivers/misc/genwqe/card_sysfs.c b/drivers/misc/genwqe/card_sysfs.c index 7232e40a3ad9..1d1c6069ebd7 100644 --- a/drivers/misc/genwqe/card_sysfs.c +++ b/drivers/misc/genwqe/card_sysfs.c @@ -91,13 +91,6 @@ static ssize_t type_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(type); -static ssize_t driver_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "%s\n", DRV_VERS_STRING); -} -static DEVICE_ATTR_RO(driver); - static ssize_t tempsens_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -256,7 +249,6 @@ static struct attribute *genwqe_attributes[] = { &dev_attr_next_bitstream.attr, &dev_attr_curr_bitstream.attr, &dev_attr_base_clock.attr, - &dev_attr_driver.attr, &dev_attr_type.attr, &dev_attr_version.attr, &dev_attr_appid.attr, @@ -268,7 +260,6 @@ static struct attribute *genwqe_attributes[] = { }; static struct attribute *genwqe_normal_attributes[] = { - &dev_attr_driver.attr, &dev_attr_type.attr, &dev_attr_version.attr, &dev_attr_appid.attr, diff --git a/drivers/misc/genwqe/genwqe_driver.h b/drivers/misc/genwqe/genwqe_driver.h index a506e9aa2d57..e39d81fd93c4 100644 --- a/drivers/misc/genwqe/genwqe_driver.h +++ b/drivers/misc/genwqe/genwqe_driver.h @@ -36,7 +36,7 @@ #include #include -#define DRV_VERS_STRING "2.0.21" +#define DRV_VERSION "2.0.25" /* * Static minor number assignement, until we decide/implement -- cgit v1.2.3 From 26d8f6f15112b8b0fbff360c360e8c42bf2bc370 Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Wed, 10 Sep 2014 16:37:48 +0200 Subject: GenWQE: Update author information Updated email address of co-author. Signed-off-by: Frank Haverkamp Signed-off-by: Michael Jung Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_base.c | 4 ++-- drivers/misc/genwqe/card_base.h | 2 +- drivers/misc/genwqe/card_ddcb.c | 2 +- drivers/misc/genwqe/card_ddcb.h | 2 +- drivers/misc/genwqe/card_debugfs.c | 2 +- drivers/misc/genwqe/card_dev.c | 2 +- drivers/misc/genwqe/card_sysfs.c | 2 +- drivers/misc/genwqe/card_utils.c | 2 +- drivers/misc/genwqe/genwqe_driver.h | 2 +- include/uapi/linux/genwqe/genwqe_card.h | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index c60ad4bd7ed6..12926c8c0609 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -5,7 +5,7 @@ * * Author: Frank Haverkamp * Author: Joerg-Stephan Vogt - * Author: Michael Jung + * Author: Michael Jung * Author: Michael Ruettger * * This program is free software; you can redistribute it and/or modify @@ -45,7 +45,7 @@ MODULE_AUTHOR("Frank Haverkamp "); MODULE_AUTHOR("Michael Ruettger "); MODULE_AUTHOR("Joerg-Stephan Vogt "); -MODULE_AUTHOR("Michal Jung "); +MODULE_AUTHOR("Michael Jung "); MODULE_DESCRIPTION("GenWQE Card"); MODULE_VERSION(DRV_VERSION); diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h index 37657d6228de..b622d204b72b 100644 --- a/drivers/misc/genwqe/card_base.h +++ b/drivers/misc/genwqe/card_base.h @@ -8,7 +8,7 @@ * * Author: Frank Haverkamp * Author: Joerg-Stephan Vogt - * Author: Michael Jung + * Author: Michael Jung * Author: Michael Ruettger * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c index 1102e1ef8104..75ff67485fdf 100644 --- a/drivers/misc/genwqe/card_ddcb.c +++ b/drivers/misc/genwqe/card_ddcb.c @@ -5,7 +5,7 @@ * * Author: Frank Haverkamp * Author: Joerg-Stephan Vogt - * Author: Michael Jung + * Author: Michael Jung * Author: Michael Ruettger * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/misc/genwqe/card_ddcb.h b/drivers/misc/genwqe/card_ddcb.h index c4f26720753e..0361a68d79a6 100644 --- a/drivers/misc/genwqe/card_ddcb.h +++ b/drivers/misc/genwqe/card_ddcb.h @@ -8,7 +8,7 @@ * * Author: Frank Haverkamp * Author: Joerg-Stephan Vogt - * Author: Michael Jung + * Author: Michael Jung * Author: Michael Ruettger * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/misc/genwqe/card_debugfs.c b/drivers/misc/genwqe/card_debugfs.c index 170a7915497c..40b425d35866 100644 --- a/drivers/misc/genwqe/card_debugfs.c +++ b/drivers/misc/genwqe/card_debugfs.c @@ -5,7 +5,7 @@ * * Author: Frank Haverkamp * Author: Joerg-Stephan Vogt - * Author: Michael Jung + * Author: Michael Jung * Author: Michael Ruettger * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index aae42555e2ca..80fdde2873de 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c @@ -5,7 +5,7 @@ * * Author: Frank Haverkamp * Author: Joerg-Stephan Vogt - * Author: Michael Jung + * Author: Michael Jung * Author: Michael Ruettger * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/misc/genwqe/card_sysfs.c b/drivers/misc/genwqe/card_sysfs.c index 1d1c6069ebd7..2c33fbca9225 100644 --- a/drivers/misc/genwqe/card_sysfs.c +++ b/drivers/misc/genwqe/card_sysfs.c @@ -5,7 +5,7 @@ * * Author: Frank Haverkamp * Author: Joerg-Stephan Vogt - * Author: Michael Jung + * Author: Michael Jung * Author: Michael Ruettger * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c index a6400f09229c..349b342c369b 100644 --- a/drivers/misc/genwqe/card_utils.c +++ b/drivers/misc/genwqe/card_utils.c @@ -5,7 +5,7 @@ * * Author: Frank Haverkamp * Author: Joerg-Stephan Vogt - * Author: Michael Jung + * Author: Michael Jung * Author: Michael Ruettger * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/misc/genwqe/genwqe_driver.h b/drivers/misc/genwqe/genwqe_driver.h index e39d81fd93c4..15355350e076 100644 --- a/drivers/misc/genwqe/genwqe_driver.h +++ b/drivers/misc/genwqe/genwqe_driver.h @@ -8,7 +8,7 @@ * * Author: Frank Haverkamp * Author: Joerg-Stephan Vogt - * Author: Michael Jung + * Author: Michael Jung * Author: Michael Ruettger * * This program is free software; you can redistribute it and/or modify diff --git a/include/uapi/linux/genwqe/genwqe_card.h b/include/uapi/linux/genwqe/genwqe_card.h index 4fc065f29255..baa93fb4cd4f 100644 --- a/include/uapi/linux/genwqe/genwqe_card.h +++ b/include/uapi/linux/genwqe/genwqe_card.h @@ -8,7 +8,7 @@ * * Author: Frank Haverkamp * Author: Joerg-Stephan Vogt - * Author: Michael Jung + * Author: Michael Jung * Author: Michael Ruettger * * This program is free software; you can redistribute it and/or modify -- cgit v1.2.3 From 2d880ccfa9be92a10ea19f5a8f7e4be2a7d45e4d Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Wed, 10 Sep 2014 16:37:49 +0200 Subject: GenWQE: Do not modify return code of genwqe_set_interrupt_capability Follow up patch to the one from Sebastian Ott. There is no need to change the return code once it fails. And Sebastians version is tested now and works nicely on our test-system. Signed-off-by: Frank Haverkamp Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_ddcb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c index 75ff67485fdf..fe8e433cdd15 100644 --- a/drivers/misc/genwqe/card_ddcb.c +++ b/drivers/misc/genwqe/card_ddcb.c @@ -1251,10 +1251,8 @@ int genwqe_setup_service_layer(struct genwqe_dev *cd) } rc = genwqe_set_interrupt_capability(cd, GENWQE_MSI_IRQS); - if (rc) { - rc = -ENODEV; + if (rc) goto stop_kthread; - } /* * We must have all wait-queues initialized when we enable the -- cgit v1.2.3 From bc407dd319bb8c3608369989d95b700d00e6cf43 Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Wed, 10 Sep 2014 16:37:50 +0200 Subject: GenWQE: Check return code of pci_sriov_enable Forgetting to check this, can lead to problems on systems which do not support SRIOV. Signed-off-by: Frank Haverkamp Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_base.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index 12926c8c0609..16672d9e1e0c 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -1320,11 +1320,14 @@ static void genwqe_err_resume(struct pci_dev *pci_dev) static int genwqe_sriov_configure(struct pci_dev *dev, int numvfs) { + int rc; struct genwqe_dev *cd = dev_get_drvdata(&dev->dev); if (numvfs > 0) { genwqe_setup_vf_jtimer(cd); - pci_enable_sriov(dev, numvfs); + rc = pci_enable_sriov(dev, numvfs); + if (rc < 0) + return rc; return numvfs; } if (numvfs == 0) { -- cgit v1.2.3 From d9c11d45b33c9226abd50a50c87e19bfa7c7a2cb Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Wed, 10 Sep 2014 16:37:51 +0200 Subject: GenWQE: Fix checkpatch complaints The checkpatch.pl script got improved. I ran it on the latest GenWQE sources and fixed what it complained about. Signed-off-by: Frank Haverkamp Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_base.c | 18 +++++++++--------- drivers/misc/genwqe/card_ddcb.c | 22 +++++++++------------- drivers/misc/genwqe/card_dev.c | 7 ++++--- drivers/misc/genwqe/card_utils.c | 5 +++-- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index 16672d9e1e0c..4cf8f82cfca2 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -388,8 +388,9 @@ static int genwqe_ffdc_buffs_alloc(struct genwqe_dev *cd) /* currently support only the debug units mentioned here */ cd->ffdc[type].entries = e; - cd->ffdc[type].regs = kmalloc(e * sizeof(struct genwqe_reg), - GFP_KERNEL); + cd->ffdc[type].regs = + kmalloc_array(e, sizeof(struct genwqe_reg), + GFP_KERNEL); /* * regs == NULL is ok, the using code treats this as no regs, * Printing warning is ok in this case. @@ -728,8 +729,8 @@ static u64 genwqe_fir_checking(struct genwqe_dev *cd) __genwqe_writeq(cd, sfir_addr, sfir); dev_dbg(&pci_dev->dev, - "[HM] Clearing 2ndary FIR 0x%08x " - "with 0x%016llx\n", sfir_addr, sfir); + "[HM] Clearing 2ndary FIR 0x%08x with 0x%016llx\n", + sfir_addr, sfir); /* * note, these cannot be error-Firs @@ -745,9 +746,8 @@ static u64 genwqe_fir_checking(struct genwqe_dev *cd) __genwqe_writeq(cd, fir_clr_addr, mask); dev_dbg(&pci_dev->dev, - "[HM] Clearing primary FIR 0x%08x " - "with 0x%016llx\n", fir_clr_addr, - mask); + "[HM] Clearing primary FIR 0x%08x with 0x%016llx\n", + fir_clr_addr, mask); } } } @@ -1209,8 +1209,8 @@ static int genwqe_probe(struct pci_dev *pci_dev, err = genwqe_health_check_start(cd); if (err < 0) { dev_err(&pci_dev->dev, - "err: cannot start health checking! " - "(err=%d)\n", err); + "err: cannot start health checking! (err=%d)\n", + err); goto out_stop_services; } } diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c index fe8e433cdd15..f10575000180 100644 --- a/drivers/misc/genwqe/card_ddcb.c +++ b/drivers/misc/genwqe/card_ddcb.c @@ -185,8 +185,7 @@ static void print_ddcb_info(struct genwqe_dev *cd, struct ddcb_queue *queue) pddcb = queue->ddcb_vaddr; for (i = 0; i < queue->ddcb_max; i++) { dev_err(&pci_dev->dev, - " %c %-3d: RETC=%03x SEQ=%04x " - "HSI=%02X SHI=%02x PRIV=%06llx CMD=%03x\n", + " %c %-3d: RETC=%03x SEQ=%04x HSI=%02X SHI=%02x PRIV=%06llx CMD=%03x\n", i == queue->ddcb_act ? '>' : ' ', i, be16_to_cpu(pddcb->retc_16), @@ -214,6 +213,7 @@ struct genwqe_ddcb_cmd *ddcb_requ_alloc(void) void ddcb_requ_free(struct genwqe_ddcb_cmd *cmd) { struct ddcb_requ *req = container_of(cmd, struct ddcb_requ, cmd); + kfree(req); } @@ -306,7 +306,7 @@ static int enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_queue *queue, new = (old | DDCB_NEXT_BE32); - wmb(); + wmb(); /* need to ensure write ordering */ icrc_hsi_shi = cmpxchg(&prev_ddcb->icrc_hsi_shi_32, old, new); if (icrc_hsi_shi == old) @@ -317,7 +317,7 @@ static int enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_queue *queue, ddcb_mark_tapped(pddcb); num = (u64)ddcb_no << 8; - wmb(); + wmb(); /* need to ensure write ordering */ __genwqe_writeq(cd, queue->IO_QUEUE_OFFSET, num); /* start queue */ return RET_DDCB_TAPPED; @@ -416,9 +416,7 @@ static int genwqe_check_ddcb_queue(struct genwqe_dev *cd, status = __genwqe_readq(cd, queue->IO_QUEUE_STATUS); dev_err(&pci_dev->dev, - "[%s] SEQN=%04x HSI=%02x RETC=%03x " - " Q_ERRCNTS=%016llx Q_STATUS=%016llx\n" - " DDCB_DMA_ADDR=%016llx\n", + "[%s] SEQN=%04x HSI=%02x RETC=%03x Q_ERRCNTS=%016llx Q_STATUS=%016llx DDCB_DMA_ADDR=%016llx\n", __func__, be16_to_cpu(pddcb->seqnum_16), pddcb->hsi, retc_16, errcnts, status, queue->ddcb_daddr + ddcb_offs); @@ -439,8 +437,7 @@ static int genwqe_check_ddcb_queue(struct genwqe_dev *cd, vcrc_16 = be16_to_cpu(pddcb->vcrc_16); if (vcrc != vcrc_16) { printk_ratelimited(KERN_ERR - "%s %s: err: wrong VCRC pre=%02x vcrc_len=%d " - "bytes vcrc_data=%04x is not vcrc_card=%04x\n", + "%s %s: err: wrong VCRC pre=%02x vcrc_len=%d bytes vcrc_data=%04x is not vcrc_card=%04x\n", GENWQE_DEVNAME, dev_name(&pci_dev->dev), pddcb->pre, VCRC_LENGTH(req->cmd.asv_length), vcrc, vcrc_16); @@ -717,8 +714,7 @@ go_home: genwqe_hexdump(pci_dev, pddcb, sizeof(*pddcb)); dev_err(&pci_dev->dev, - "[%s] err: DDCB#%d not purged and not completed " - "after %d seconds QSTAT=%016llx!!\n", + "[%s] err: DDCB#%d not purged and not completed after %d seconds QSTAT=%016llx!!\n", __func__, req->num, genwqe_ddcb_software_timeout, queue_status); @@ -1344,8 +1340,8 @@ int genwqe_finish_queue(struct genwqe_dev *cd) break; dev_dbg(&pci_dev->dev, - " DEBUG [%d/%d] waiting for queue to get empty: " - "%d requests!\n", i, waitmax, in_flight); + " DEBUG [%d/%d] waiting for queue to get empty: %d requests!\n", + i, waitmax, in_flight); /* * Severe severe error situation: The card itself has diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index 80fdde2873de..59e0081acc8f 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c @@ -213,9 +213,9 @@ static void genwqe_remove_mappings(struct genwqe_file *cfile) * GENWQE_MAPPING_SGL_TEMP should be removed by tidy up code. */ dev_err(&pci_dev->dev, - "[%s] %d. cleanup mapping: u_vaddr=%p " - "u_kaddr=%016lx dma_addr=%lx\n", __func__, i++, - dma_map->u_vaddr, (unsigned long)dma_map->k_vaddr, + "[%s] %d. cleanup mapping: u_vaddr=%p u_kaddr=%016lx dma_addr=%lx\n", + __func__, i++, dma_map->u_vaddr, + (unsigned long)dma_map->k_vaddr, (unsigned long)dma_map->dma_addr); if (dma_map->type == GENWQE_MAPPING_RAW) { @@ -346,6 +346,7 @@ static int genwqe_open(struct inode *inode, struct file *filp) static int genwqe_fasync(int fd, struct file *filp, int mode) { struct genwqe_file *cdev = (struct genwqe_file *)filp->private_data; + return fasync_helper(fd, filp, mode, &cdev->async_queue); } diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c index 349b342c369b..7cb3b7e41739 100644 --- a/drivers/misc/genwqe/card_utils.c +++ b/drivers/misc/genwqe/card_utils.c @@ -150,6 +150,7 @@ int genwqe_read_app_id(struct genwqe_dev *cd, char *app_name, int len) memset(app_name, 0, len); for (i = 0, j = 0; j < min(len, 4); j++) { char ch = (char)((app_id >> (24 - j*8)) & 0xff); + if (ch == ' ') continue; app_name[i++] = isprint(ch) ? ch : 'X'; @@ -304,8 +305,7 @@ int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl, sgl->nr_pages = DIV_ROUND_UP(sgl->fpage_offs + user_size, PAGE_SIZE); sgl->lpage_size = (user_size - sgl->fpage_size) % PAGE_SIZE; - dev_dbg(&pci_dev->dev, "[%s] uaddr=%p usize=%8ld nr_pages=%ld " - "fpage_offs=%lx fpage_size=%ld lpage_size=%ld\n", + dev_dbg(&pci_dev->dev, "[%s] uaddr=%p usize=%8ld nr_pages=%ld fpage_offs=%lx fpage_size=%ld lpage_size=%ld\n", __func__, user_addr, user_size, sgl->nr_pages, sgl->fpage_offs, sgl->fpage_size, sgl->lpage_size); @@ -662,6 +662,7 @@ int genwqe_user_vunmap(struct genwqe_dev *cd, struct dma_mapping *m, u8 genwqe_card_type(struct genwqe_dev *cd) { u64 card_type = cd->slu_unitcfg; + return (u8)((card_type & IO_SLU_UNITCFG_TYPE_MASK) >> 20); } -- cgit v1.2.3 From 08e4906cc29d092ae2da0ff089efe1488e584d3c Mon Sep 17 00:00:00 2001 From: "Eberhard S. Amann" Date: Wed, 10 Sep 2014 16:37:52 +0200 Subject: GenWQE: Fix problem when reading HSI and Retc This patch fixes a problem we found during debug on PPC64 when reading HSI status and Retc. Signed-off-by: Eberhard S. Amann Signed-off-by: Frank Haverkamp Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_ddcb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c index f10575000180..51480e4f8054 100644 --- a/drivers/misc/genwqe/card_ddcb.c +++ b/drivers/misc/genwqe/card_ddcb.c @@ -390,8 +390,9 @@ static int genwqe_check_ddcb_queue(struct genwqe_dev *cd, 0x00000000) goto go_home; /* not completed, continue waiting */ - /* Note: DDCB could be purged */ + wmb(); /* Add sync to decouple prev. read operations */ + /* Note: DDCB could be purged */ req = queue->ddcb_req[queue->ddcb_act]; if (req == NULL) { /* this occurs if DDCB is purged, not an error */ -- cgit v1.2.3 From 1451f414639465995dfc1f820aa1a64723cbd662 Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Wed, 10 Sep 2014 16:37:53 +0200 Subject: GenWQE: Support blocking when DDCB queue is busy When the GenWQE hardware queue was busy, the driver returned simply -EBUSY. This caused polling by applications which increased the load on the already busy system. This change implements the possiblity to sleep on a waitqueue instead when the DDCB queue is busy. The requestor is woken up when there is free space on the queue again. The old way to get -EBUSY is still available if the device is openend with O_NONBLOCKING. The default is now blocking behavior. Signed-off-by: Frank Haverkamp Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_base.h | 17 +++++++++------ drivers/misc/genwqe/card_ddcb.c | 44 +++++++++++++++++++++++++++++--------- drivers/misc/genwqe/card_debugfs.c | 6 ++++-- drivers/misc/genwqe/card_dev.c | 12 +++++++---- 4 files changed, 57 insertions(+), 22 deletions(-) diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h index b622d204b72b..c64d7cad1085 100644 --- a/drivers/misc/genwqe/card_base.h +++ b/drivers/misc/genwqe/card_base.h @@ -201,7 +201,8 @@ static inline void genwqe_mapping_init(struct dma_mapping *m, * @ddcb_seq: Sequence number of last DDCB * @ddcbs_in_flight: Currently enqueued DDCBs * @ddcbs_completed: Number of already completed DDCBs - * @busy: Number of -EBUSY returns + * @return_on_busy: Number of -EBUSY returns on full queue + * @wait_on_busy: Number of waits on full queue * @ddcb_daddr: DMA address of first DDCB in the queue * @ddcb_vaddr: Kernel virtual address of first DDCB in the queue * @ddcb_req: Associated requests (one per DDCB) @@ -218,7 +219,8 @@ struct ddcb_queue { unsigned int ddcbs_in_flight; /* number of ddcbs in processing */ unsigned int ddcbs_completed; unsigned int ddcbs_max_in_flight; - unsigned int busy; /* how many times -EBUSY? */ + unsigned int return_on_busy; /* how many times -EBUSY? */ + unsigned int wait_on_busy; dma_addr_t ddcb_daddr; /* DMA address */ struct ddcb *ddcb_vaddr; /* kernel virtual addr for DDCBs */ @@ -226,7 +228,7 @@ struct ddcb_queue { wait_queue_head_t *ddcb_waitqs; /* waitqueue per ddcb */ spinlock_t ddcb_lock; /* exclusive access to queue */ - wait_queue_head_t ddcb_waitq; /* wait for ddcb processing */ + wait_queue_head_t busy_waitq; /* wait for ddcb processing */ /* registers or the respective queue to be used */ u32 IO_QUEUE_CONFIG; @@ -508,7 +510,7 @@ static inline bool dma_mapping_used(struct dma_mapping *m) * buildup and teardown. */ int __genwqe_execute_ddcb(struct genwqe_dev *cd, - struct genwqe_ddcb_cmd *cmd); + struct genwqe_ddcb_cmd *cmd, unsigned int f_flags); /** * __genwqe_execute_raw_ddcb() - Execute DDCB request without addr translation @@ -520,9 +522,12 @@ int __genwqe_execute_ddcb(struct genwqe_dev *cd, * modification. */ int __genwqe_execute_raw_ddcb(struct genwqe_dev *cd, - struct genwqe_ddcb_cmd *cmd); + struct genwqe_ddcb_cmd *cmd, + unsigned int f_flags); +int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, + struct ddcb_requ *req, + unsigned int f_flags); -int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req); int __genwqe_wait_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req); int __genwqe_purge_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req); diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c index 51480e4f8054..6d51e5f08664 100644 --- a/drivers/misc/genwqe/card_ddcb.c +++ b/drivers/misc/genwqe/card_ddcb.c @@ -448,8 +448,10 @@ static int genwqe_check_ddcb_queue(struct genwqe_dev *cd, queue->ddcbs_completed++; queue->ddcbs_in_flight--; - /* wake up process waiting for this DDCB */ + /* wake up process waiting for this DDCB, and + processes on the busy queue */ wake_up_interruptible(&queue->ddcb_waitqs[queue->ddcb_act]); + wake_up_interruptible(&queue->busy_waitq); pick_next_one: queue->ddcb_act = (queue->ddcb_act + 1) % queue->ddcb_max; @@ -745,14 +747,16 @@ int genwqe_init_debug_data(struct genwqe_dev *cd, struct genwqe_debug_data *d) /** * __genwqe_enqueue_ddcb() - Enqueue a DDCB - * @cd: pointer to genwqe device descriptor - * @req: pointer to DDCB execution request + * @cd: pointer to genwqe device descriptor + * @req: pointer to DDCB execution request + * @f_flags: file mode: blocking, non-blocking * * Return: 0 if enqueuing succeeded * -EIO if card is unusable/PCIe problems * -EBUSY if enqueuing failed */ -int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req) +int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req, + unsigned int f_flags) { struct ddcb *pddcb; unsigned long flags; @@ -760,6 +764,7 @@ int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req) struct pci_dev *pci_dev = cd->pci_dev; u16 icrc; + retry: if (cd->card_state != GENWQE_CARD_USED) { printk_ratelimited(KERN_ERR "%s %s: [%s] Card is unusable/PCIe problem Req#%d\n", @@ -785,9 +790,24 @@ int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req) pddcb = get_next_ddcb(cd, queue, &req->num); /* get ptr and num */ if (pddcb == NULL) { + int rc; + spin_unlock_irqrestore(&queue->ddcb_lock, flags); - queue->busy++; - return -EBUSY; + + if (f_flags & O_NONBLOCK) { + queue->return_on_busy++; + return -EBUSY; + } + + queue->wait_on_busy++; + rc = wait_event_interruptible(queue->busy_waitq, + queue_free_ddcbs(queue) != 0); + dev_dbg(&pci_dev->dev, "[%s] waiting for free DDCB: rc=%d\n", + __func__, rc); + if (rc == -ERESTARTSYS) + return rc; /* interrupted by a signal */ + + goto retry; } if (queue->ddcb_req[req->num] != NULL) { @@ -890,9 +910,11 @@ int __genwqe_enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_requ *req) * __genwqe_execute_raw_ddcb() - Setup and execute DDCB * @cd: pointer to genwqe device descriptor * @req: user provided DDCB request + * @f_flags: file mode: blocking, non-blocking */ int __genwqe_execute_raw_ddcb(struct genwqe_dev *cd, - struct genwqe_ddcb_cmd *cmd) + struct genwqe_ddcb_cmd *cmd, + unsigned int f_flags) { int rc = 0; struct pci_dev *pci_dev = cd->pci_dev; @@ -908,7 +930,7 @@ int __genwqe_execute_raw_ddcb(struct genwqe_dev *cd, __func__, cmd->asiv_length); return -EINVAL; } - rc = __genwqe_enqueue_ddcb(cd, req); + rc = __genwqe_enqueue_ddcb(cd, req, f_flags); if (rc != 0) return rc; @@ -1014,7 +1036,8 @@ static int setup_ddcb_queue(struct genwqe_dev *cd, struct ddcb_queue *queue) queue->ddcbs_in_flight = 0; /* statistics */ queue->ddcbs_max_in_flight = 0; queue->ddcbs_completed = 0; - queue->busy = 0; + queue->return_on_busy = 0; + queue->wait_on_busy = 0; queue->ddcb_seq = 0x100; /* start sequence number */ queue->ddcb_max = genwqe_ddcb_max; /* module parameter */ @@ -1054,7 +1077,7 @@ static int setup_ddcb_queue(struct genwqe_dev *cd, struct ddcb_queue *queue) queue->ddcb_next = 0; /* queue is empty */ spin_lock_init(&queue->ddcb_lock); - init_waitqueue_head(&queue->ddcb_waitq); + init_waitqueue_head(&queue->busy_waitq); val64 = ((u64)(queue->ddcb_max - 1) << 8); /* lastptr */ __genwqe_writeq(cd, queue->IO_QUEUE_CONFIG, 0x07); /* iCRC/vCRC */ @@ -1302,6 +1325,7 @@ static int queue_wake_up_all(struct genwqe_dev *cd) for (i = 0; i < queue->ddcb_max; i++) wake_up_interruptible(&queue->ddcb_waitqs[queue->ddcb_act]); + wake_up_interruptible(&queue->busy_waitq); spin_unlock_irqrestore(&queue->ddcb_lock, flags); return 0; diff --git a/drivers/misc/genwqe/card_debugfs.c b/drivers/misc/genwqe/card_debugfs.c index 40b425d35866..c715534e7fe7 100644 --- a/drivers/misc/genwqe/card_debugfs.c +++ b/drivers/misc/genwqe/card_debugfs.c @@ -244,14 +244,16 @@ static int genwqe_ddcb_info_show(struct seq_file *s, void *unused) " ddcbs_in_flight: %u\n" " ddcbs_max_in_flight: %u\n" " ddcbs_completed: %u\n" - " busy: %u\n" + " return_on_busy: %u\n" + " wait_on_busy: %u\n" " irqs_processed: %u\n", queue->ddcb_max, (long long)queue->ddcb_daddr, (long long)queue->ddcb_daddr + (queue->ddcb_max * DDCB_LENGTH), (long long)queue->ddcb_vaddr, queue->ddcbs_in_flight, queue->ddcbs_max_in_flight, queue->ddcbs_completed, - queue->busy, cd->irqs_processed); + queue->return_on_busy, queue->wait_on_busy, + cd->irqs_processed); /* Hardware State */ seq_printf(s, " 0x%08x 0x%016llx IO_QUEUE_CONFIG\n" diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index 59e0081acc8f..5918586f2f76 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c @@ -516,6 +516,7 @@ static int do_flash_update(struct genwqe_file *cfile, u32 crc; u8 cmdopts; struct genwqe_dev *cd = cfile->cd; + struct file *filp = cfile->filp; struct pci_dev *pci_dev = cd->pci_dev; if ((load->size & 0x3) != 0) @@ -610,7 +611,7 @@ static int do_flash_update(struct genwqe_file *cfile, /* For Genwqe5 we get back the calculated CRC */ *(u64 *)&req->asv[0] = 0ULL; /* 0x80 */ - rc = __genwqe_execute_raw_ddcb(cd, req); + rc = __genwqe_execute_raw_ddcb(cd, req, filp->f_flags); load->retc = req->retc; load->attn = req->attn; @@ -650,6 +651,7 @@ static int do_flash_read(struct genwqe_file *cfile, u8 *xbuf; u8 cmdopts; struct genwqe_dev *cd = cfile->cd; + struct file *filp = cfile->filp; struct pci_dev *pci_dev = cd->pci_dev; struct genwqe_ddcb_cmd *cmd; @@ -727,7 +729,7 @@ static int do_flash_read(struct genwqe_file *cfile, /* we only get back the calculated CRC */ *(u64 *)&cmd->asv[0] = 0ULL; /* 0x80 */ - rc = __genwqe_execute_raw_ddcb(cd, cmd); + rc = __genwqe_execute_raw_ddcb(cd, cmd, filp->f_flags); load->retc = cmd->retc; load->attn = cmd->attn; @@ -988,13 +990,14 @@ static int genwqe_execute_ddcb(struct genwqe_file *cfile, { int rc; struct genwqe_dev *cd = cfile->cd; + struct file *filp = cfile->filp; struct ddcb_requ *req = container_of(cmd, struct ddcb_requ, cmd); rc = ddcb_cmd_fixups(cfile, req); if (rc != 0) return rc; - rc = __genwqe_execute_raw_ddcb(cd, cmd); + rc = __genwqe_execute_raw_ddcb(cd, cmd, filp->f_flags); ddcb_cmd_cleanup(cfile, req); return rc; } @@ -1006,6 +1009,7 @@ static int do_execute_ddcb(struct genwqe_file *cfile, struct genwqe_ddcb_cmd *cmd; struct ddcb_requ *req; struct genwqe_dev *cd = cfile->cd; + struct file *filp = cfile->filp; cmd = ddcb_requ_alloc(); if (cmd == NULL) @@ -1021,7 +1025,7 @@ static int do_execute_ddcb(struct genwqe_file *cfile, if (!raw) rc = genwqe_execute_ddcb(cfile, cmd); else - rc = __genwqe_execute_raw_ddcb(cd, cmd); + rc = __genwqe_execute_raw_ddcb(cd, cmd, filp->f_flags); /* Copy back only the modifed fields. Do not copy ASIV back since the copy got modified by the driver. */ -- cgit v1.2.3 From 95e838c915edbdde366d111905245171ac99c2cc Mon Sep 17 00:00:00 2001 From: Federico Vaga Date: Mon, 1 Sep 2014 13:49:56 +0200 Subject: ipoctal: clear break interrupt as soon as it occurs In some condition we receive the break interrupt but nothing is putted in the Rx FIFO and the correspondend bit in the status register is not set. Thus, no-one clear the interrupt and the handler will be called forever. This patch clear the break interrupt as soon as it occurs. Then, if the break character '\0' is putted in the fifo we will manage it. We can also unmask the Break interrupt but its bit in ISR is still set on break. So I think is better to keep the registers clean. Signed-off-by: Federico Vaga Acked-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/ipack/devices/ipoctal.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index 42700815d05f..035d5449227e 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -175,7 +175,6 @@ static void ipoctal_irq_rx(struct ipoctal_channel *channel, u8 sr) flag = TTY_FRAME; } if (sr & SR_RECEIVED_BREAK) { - iowrite8(CR_CMD_RESET_BREAK_CHANGE, &channel->regs->w.cr); channel->stats.rcv_break++; flag = TTY_BREAK; } @@ -220,6 +219,9 @@ static void ipoctal_irq_channel(struct ipoctal_channel *channel) isr = ioread8(&channel->block_regs->r.isr); sr = ioread8(&channel->regs->r.sr); + if (isr & (IMR_DELTA_BREAK_A | IMR_DELTA_BREAK_B)) + iowrite8(CR_CMD_RESET_BREAK_CHANGE, &channel->regs->w.cr); + if ((sr & SR_TX_EMPTY) && (channel->nb_bytes == 0)) { iowrite8(CR_DISABLE_TX, &channel->regs->w.cr); /* In case of RS-485, change from TX to RX when finishing TX. -- cgit v1.2.3 From 2e45354645f77e83fe3832f150acdcfeff45f44c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 29 Aug 2014 11:42:56 +0300 Subject: VMCI: integer overflow in vmci_datagram_dispatch() This is untrusted user data from vmci_host_do_send_datagram() so the VMCI_DG_SIZE() macro can have an integer overflow. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/misc/vmw_vmci/vmci_datagram.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/misc/vmw_vmci/vmci_datagram.c b/drivers/misc/vmw_vmci/vmci_datagram.c index f3cdd904fe4d..822665245588 100644 --- a/drivers/misc/vmw_vmci/vmci_datagram.c +++ b/drivers/misc/vmw_vmci/vmci_datagram.c @@ -328,7 +328,8 @@ int vmci_datagram_dispatch(u32 context_id, BUILD_BUG_ON(sizeof(struct vmci_datagram) != 24); - if (VMCI_DG_SIZE(dg) > VMCI_MAX_DG_SIZE) { + if (dg->payload_size > VMCI_MAX_DG_SIZE || + VMCI_DG_SIZE(dg) > VMCI_MAX_DG_SIZE) { pr_devel("Payload (size=%llu bytes) too big to send\n", (unsigned long long)dg->payload_size); return VMCI_ERROR_INVALID_ARGS; -- cgit v1.2.3 From 06c88b0d7ad87540405aea7f91d98ef43be04c95 Mon Sep 17 00:00:00 2001 From: Steven Honeyman Date: Fri, 5 Sep 2014 18:03:42 +0100 Subject: i8k: Add support for Dell Latitude E6540 Add support for the Dell Latitude E6540 which needs a different fan speed multiplier. Signed-off-by: Steven Honeyman Reviewed-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/char/i8k.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index 65525c7e903c..34174d01462e 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c @@ -651,6 +651,7 @@ struct i8k_config_data { enum i8k_configs { DELL_LATITUDE_D520, + DELL_LATITUDE_E6540, DELL_PRECISION_490, DELL_STUDIO, DELL_XPS_M140, @@ -661,6 +662,10 @@ static const struct i8k_config_data i8k_config_data[] = { .fan_mult = 1, .fan_max = I8K_FAN_TURBO, }, + [DELL_LATITUDE_E6540] = { + .fan_mult = 1, + .fan_max = I8K_FAN_HIGH, + }, [DELL_PRECISION_490] = { .fan_mult = 1, .fan_max = I8K_FAN_TURBO, @@ -705,6 +710,14 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = { }, .driver_data = (void *)&i8k_config_data[DELL_LATITUDE_D520], }, + { + .ident = "Dell Latitude E6540", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6540"), + }, + .driver_data = (void *)&i8k_config_data[DELL_LATITUDE_E6540], + }, { .ident = "Dell Latitude 2", .matches = { -- cgit v1.2.3 From fdeebcc62279119dbeafbc1a2e39e773839025fd Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 27 Aug 2014 16:25:31 -0700 Subject: Drivers: hv: vmbus: Cleanup vmbus_post_msg() Posting messages to the host can fail because of transient resource related failures. Correctly deal with these failures and increase the number of attempts to post the message before giving up. In this version of the patch, I have normalized the error code to Linux error code. Signed-off-by: K. Y. Srinivasan Cc: Tested-by: Sitsofe Wheeler Signed-off-by: Greg Kroah-Hartman --- drivers/hv/connection.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index ae22e3c1fc4c..e206619b946e 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -427,10 +427,21 @@ int vmbus_post_msg(void *buffer, size_t buflen) * insufficient resources. Retry the operation a couple of * times before giving up. */ - while (retries < 3) { - ret = hv_post_message(conn_id, 1, buffer, buflen); - if (ret != HV_STATUS_INSUFFICIENT_BUFFERS) + while (retries < 10) { + ret = hv_post_message(conn_id, 1, buffer, buflen); + + switch (ret) { + case HV_STATUS_INSUFFICIENT_BUFFERS: + ret = -ENOMEM; + case -ENOMEM: + break; + case HV_STATUS_SUCCESS: return ret; + default: + pr_err("hv_post_msg() failed; error code:%d\n", ret); + return -EINVAL; + } + retries++; msleep(100); } -- cgit v1.2.3 From 66be653083057358724d56d817e870e53fb81ca7 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 27 Aug 2014 16:25:32 -0700 Subject: Drivers: hv: vmbus: Cleanup vmbus_teardown_gpadl() Eliminate calls to BUG_ON() by properly handling errors. In cases where rollback is possible, we will return the appropriate error to have the calling code decide how to rollback state. In the case where we are transferring ownership of the guest physical pages to the host, we will wait for the host to respond. Signed-off-by: K. Y. Srinivasan Cc: Tested-by: Sitsofe Wheeler Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 531a593912ec..020631453394 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -435,7 +435,7 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) struct vmbus_channel_gpadl_teardown *msg; struct vmbus_channel_msginfo *info; unsigned long flags; - int ret, t; + int ret; info = kmalloc(sizeof(*info) + sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL); @@ -457,11 +457,12 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_gpadl_teardown)); - BUG_ON(ret != 0); - t = wait_for_completion_timeout(&info->waitevent, 5*HZ); - BUG_ON(t == 0); + if (ret) + goto post_msg_err; + + wait_for_completion(&info->waitevent); - /* Received a torndown response */ +post_msg_err: spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_del(&info->msglistentry); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); -- cgit v1.2.3 From 72c6b71c245dac8f371167d97ef471b367d0b66b Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 27 Aug 2014 16:25:34 -0700 Subject: Drivers: hv: vmbus: Cleanup vmbus_establish_gpadl() Eliminate the call to BUG_ON() by waiting for the host to respond. We are trying to reclaim the ownership of memory that was given to the host and so we will have to wait until the host responds. Signed-off-by: K. Y. Srinivasan Cc: Tested-by: Sitsofe Wheeler Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 020631453394..3788a181f176 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -363,7 +363,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, u32 next_gpadl_handle; unsigned long flags; int ret = 0; - int t; next_gpadl_handle = atomic_read(&vmbus_connection.next_gpadl_handle); atomic_inc(&vmbus_connection.next_gpadl_handle); @@ -410,9 +409,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, } } - t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ); - BUG_ON(t == 0); - + wait_for_completion(&msginfo->waitevent); /* At this point, we received the gpadl created msg */ *gpadl_handle = gpadlmsg->gpadl; -- cgit v1.2.3 From 45d727cee9e200f5b351528b9fb063b69cf702c8 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 27 Aug 2014 16:25:35 -0700 Subject: Drivers: hv: vmbus: Fix a bug in vmbus_open() Fix a bug in vmbus_open() and properly propagate the error. I would like to thank Dexuan Cui for identifying the issue. Signed-off-by: K. Y. Srinivasan Cc: Tested-by: Sitsofe Wheeler Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 3788a181f176..b4eebe34ca91 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -165,8 +165,10 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, ret = vmbus_post_msg(open_msg, sizeof(struct vmbus_channel_open_channel)); - if (ret != 0) + if (ret != 0) { + err = ret; goto error1; + } t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ); if (t == 0) { -- cgit v1.2.3 From 98d731bb064a9d1817a6ca9bf8b97051334a7cfe Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 27 Aug 2014 16:25:33 -0700 Subject: Drivers: hv: vmbus: Cleanup vmbus_close_internal() Eliminate calls to BUG_ON() in vmbus_close_internal(). We have chosen to potentially leak memory, than crash the guest in case of failures. In this version of the patch I have addressed comments from Dan Carpenter (dan.carpenter@oracle.com). Signed-off-by: K. Y. Srinivasan Cc: Tested-by: Sitsofe Wheeler Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index b4eebe34ca91..19bad59073e6 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -478,7 +478,7 @@ static void reset_channel_cb(void *arg) channel->onchannel_callback = NULL; } -static void vmbus_close_internal(struct vmbus_channel *channel) +static int vmbus_close_internal(struct vmbus_channel *channel) { struct vmbus_channel_close_channel *msg; int ret; @@ -501,11 +501,28 @@ static void vmbus_close_internal(struct vmbus_channel *channel) ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel)); - BUG_ON(ret != 0); + if (ret) { + pr_err("Close failed: close post msg return is %d\n", ret); + /* + * If we failed to post the close msg, + * it is perhaps better to leak memory. + */ + return ret; + } + /* Tear down the gpadl for the channel's ring buffer */ - if (channel->ringbuffer_gpadlhandle) - vmbus_teardown_gpadl(channel, - channel->ringbuffer_gpadlhandle); + if (channel->ringbuffer_gpadlhandle) { + ret = vmbus_teardown_gpadl(channel, + channel->ringbuffer_gpadlhandle); + if (ret) { + pr_err("Close failed: teardown gpadl return %d\n", ret); + /* + * If we failed to teardown gpadl, + * it is perhaps better to leak memory. + */ + return ret; + } + } /* Cleanup the ring buffers for this channel */ hv_ringbuffer_cleanup(&channel->outbound); @@ -514,7 +531,7 @@ static void vmbus_close_internal(struct vmbus_channel *channel) free_pages((unsigned long)channel->ringbuffer_pages, get_order(channel->ringbuffer_pagecount * PAGE_SIZE)); - + return ret; } /* -- cgit v1.2.3 From b29ef3546aecb253a5552b198cef23750d56e1e4 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 28 Aug 2014 18:29:52 -0700 Subject: Drivers: hv: vmbus: Cleanup hv_post_message() Minimize failures in this function by pre-allocating the buffer for posting messages. The hypercall for posting the message can fail for a number of reasons: 1. Transient resource related issues 2. Buffer alignment 3. Buffer cannot span a page boundry We address issues 2 and 3 by preallocating a per-cpu page for the buffer. Transient resource related failures are handled by retrying by the callers of this function. This patch is based on the investigation done by Dexuan Cui . I would like to thank Sitsofe Wheeler for reporting the issue and helping in debuggging. Signed-off-by: K. Y. Srinivasan Reported-by: Sitsofe Wheeler Cc: Tested-by: Sitsofe Wheeler Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv.c | 27 +++++++++++++++------------ drivers/hv/hyperv_vmbus.h | 4 ++++ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index edfc8488cb03..3e4235c7a47f 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -138,6 +138,8 @@ int hv_init(void) memset(hv_context.synic_event_page, 0, sizeof(void *) * NR_CPUS); memset(hv_context.synic_message_page, 0, sizeof(void *) * NR_CPUS); + memset(hv_context.post_msg_page, 0, + sizeof(void *) * NR_CPUS); memset(hv_context.vp_index, 0, sizeof(int) * NR_CPUS); memset(hv_context.event_dpc, 0, @@ -217,26 +219,18 @@ int hv_post_message(union hv_connection_id connection_id, enum hv_message_type message_type, void *payload, size_t payload_size) { - struct aligned_input { - u64 alignment8; - struct hv_input_post_message msg; - }; struct hv_input_post_message *aligned_msg; u16 status; - unsigned long addr; if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT) return -EMSGSIZE; - addr = (unsigned long)kmalloc(sizeof(struct aligned_input), GFP_ATOMIC); - if (!addr) - return -ENOMEM; - aligned_msg = (struct hv_input_post_message *) - (ALIGN(addr, HV_HYPERCALL_PARAM_ALIGN)); + hv_context.post_msg_page[get_cpu()]; aligned_msg->connectionid = connection_id; + aligned_msg->reserved = 0; aligned_msg->message_type = message_type; aligned_msg->payload_size = payload_size; memcpy((void *)aligned_msg->payload, payload, payload_size); @@ -244,8 +238,7 @@ int hv_post_message(union hv_connection_id connection_id, status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL) & 0xFFFF; - kfree((void *)addr); - + put_cpu(); return status; } @@ -294,6 +287,14 @@ int hv_synic_alloc(void) pr_err("Unable to allocate SYNIC event page\n"); goto err; } + + hv_context.post_msg_page[cpu] = + (void *)get_zeroed_page(GFP_ATOMIC); + + if (hv_context.post_msg_page[cpu] == NULL) { + pr_err("Unable to allocate post msg page\n"); + goto err; + } } return 0; @@ -308,6 +309,8 @@ static void hv_synic_free_cpu(int cpu) free_page((unsigned long)hv_context.synic_event_page[cpu]); if (hv_context.synic_message_page[cpu]) free_page((unsigned long)hv_context.synic_message_page[cpu]); + if (hv_context.post_msg_page[cpu]) + free_page((unsigned long)hv_context.post_msg_page[cpu]); } void hv_synic_free(void) diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 22b750749a39..c386d8dc7223 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -515,6 +515,10 @@ struct hv_context { * per-cpu list of the channels based on their CPU affinity. */ struct list_head percpu_list[NR_CPUS]; + /* + * buffer to post messages to the host. + */ + void *post_msg_page[NR_CPUS]; }; extern struct hv_context hv_context; -- cgit v1.2.3 From 2115b5617adf2eecca49e78f3810f359ddc5c396 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 28 Aug 2014 18:29:53 -0700 Subject: Drivers: hv: vmbus: Properly protect calls to smp_processor_id() Disable preemption when sampling current processor ID when preemption is otherwise possible. Signed-off-by: K. Y. Srinivasan Tested-by: Sitsofe Wheeler Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel.c | 7 +++++-- drivers/hv/channel_mgmt.c | 21 +++++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 19bad59073e6..433f72a1c006 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -486,11 +486,14 @@ static int vmbus_close_internal(struct vmbus_channel *channel) channel->state = CHANNEL_OPEN_STATE; channel->sc_creation_callback = NULL; /* Stop callback and cancel the timer asap */ - if (channel->target_cpu != smp_processor_id()) + if (channel->target_cpu != get_cpu()) { + put_cpu(); smp_call_function_single(channel->target_cpu, reset_channel_cb, channel, true); - else + } else { reset_channel_cb(channel); + put_cpu(); + } /* Send a closing message */ diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index ed9350d42764..a2d1a9612c86 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -224,11 +224,14 @@ static void vmbus_process_rescind_offer(struct work_struct *work) msg.header.msgtype = CHANNELMSG_RELID_RELEASED; vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released)); - if (channel->target_cpu != smp_processor_id()) + if (channel->target_cpu != get_cpu()) { + put_cpu(); smp_call_function_single(channel->target_cpu, percpu_channel_deq, channel, true); - else + } else { percpu_channel_deq(channel); + put_cpu(); + } if (channel->primary_channel == NULL) { spin_lock_irqsave(&vmbus_connection.channel_lock, flags); @@ -294,12 +297,15 @@ static void vmbus_process_offer(struct work_struct *work) spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); if (enq) { - if (newchannel->target_cpu != smp_processor_id()) + if (newchannel->target_cpu != get_cpu()) { + put_cpu(); smp_call_function_single(newchannel->target_cpu, percpu_channel_enq, newchannel, true); - else + } else { percpu_channel_enq(newchannel); + put_cpu(); + } } if (!fnew) { /* @@ -314,12 +320,15 @@ static void vmbus_process_offer(struct work_struct *work) list_add_tail(&newchannel->sc_list, &channel->sc_list); spin_unlock_irqrestore(&channel->sc_lock, flags); - if (newchannel->target_cpu != smp_processor_id()) + if (newchannel->target_cpu != get_cpu()) { + put_cpu(); smp_call_function_single(newchannel->target_cpu, percpu_channel_enq, newchannel, true); - else + } else { percpu_channel_enq(newchannel); + put_cpu(); + } newchannel->state = CHANNEL_OPEN_STATE; if (channel->sc_creation_callback != NULL) -- cgit v1.2.3 From bc5a5b02331a3175a5fca20a4beba249e573b672 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 2 Sep 2014 19:21:47 -0700 Subject: Drivers: hv: util: Properly pack the data for file copy functionality Properly pack the data for file copy functionality. Patch based on investigation done by Matej Muzila Signed-off-by: K. Y. Srinivasan Reported-by: Cc: Acked-by: Jason Wang Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/hyperv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/hyperv.h b/include/uapi/linux/hyperv.h index 78e4a86030dd..0a8e6badb29b 100644 --- a/include/uapi/linux/hyperv.h +++ b/include/uapi/linux/hyperv.h @@ -137,7 +137,7 @@ struct hv_do_fcopy { __u64 offset; __u32 size; __u8 data[DATA_FRAGMENT]; -}; +} __attribute__((packed)); /* * An implementation of HyperV key value pair (KVP) functionality for Linux. -- cgit v1.2.3 From 046c7911b224267062ab1caeabbf11bc46e9c152 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 5 Sep 2014 17:29:12 -0700 Subject: Drivers: hv: vmbus: Enable interrupt driven flow control In win8 we have a feature that allows for interrupt driven flow management for host/guest communication. For instance, if the host were blocked because there was no space available in the ringbuffer, the host could request that the guest send an interrupt when space becomes available in the ringbuffer (when the guest drains the ringbuffer). While this feature was implemented in the guest a while ago, we had not advertised that the guest supported this feature. This patch advertises the support to the host. For pre-win8 hosts, this has no effect since the size of the ringbuffer control structure has not changed and all changes have been backward compatible - unused/reserved space has been used to implement this feature. In this version of the patch I have cleaned up the commit log based on feedback from Greg KH. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/ring_buffer.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index 15db66b74141..6361d124f67d 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c @@ -361,6 +361,11 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, ring_info->ring_buffer->read_index = ring_info->ring_buffer->write_index = 0; + /* + * Set the feature bit for enabling flow control. + */ + ring_info->ring_buffer->feature_bits.value = 1; + ring_info->ring_size = buflen; ring_info->ring_datasize = buflen - sizeof(struct hv_ring_buffer); -- cgit v1.2.3 From 1beeb4b9fbb27432f93ae8fe157228b7b897974a Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Mon, 29 Sep 2014 16:31:33 +0300 Subject: mei: add hbm and pg state in devstate debugfs print Add hbm state, pg enablement and state to devstate file in debugfs (/mei/devstate) Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/debugfs.c | 7 ++++++- drivers/misc/mei/hbm.c | 16 ++++++++++++++++ drivers/misc/mei/hbm.h | 2 ++ drivers/misc/mei/init.c | 12 ++++++++++++ drivers/misc/mei/mei_dev.h | 2 ++ 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index 3b032881622d..2399b3181e6c 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c @@ -134,8 +134,13 @@ static ssize_t mei_dbgfs_read_devstate(struct file *fp, char __user *ubuf, if (!buf) return -ENOMEM; - pos += scnprintf(buf + pos, bufsz - pos, "%s\n", + pos += scnprintf(buf + pos, bufsz - pos, "dev: %s\n", mei_dev_state_str(dev->dev_state)); + pos += scnprintf(buf + pos, bufsz - pos, "hbm: %s\n", + mei_hbm_state_str(dev->hbm_state)); + pos += scnprintf(buf + pos, bufsz - pos, "pg: %s, %s\n", + mei_pg_is_enabled(dev) ? "ENABLED" : "DISABLED", + mei_pg_state_str(mei_pg_state(dev))); ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, pos); kfree(buf); return ret; diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 9fc051b7f1a3..3311b5c323af 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -56,6 +56,22 @@ static const char *mei_cl_conn_status_str(enum mei_cl_connect_status status) #undef MEI_CL_CCS } +const char *mei_hbm_state_str(enum mei_hbm_state state) +{ +#define MEI_HBM_STATE(state) case MEI_HBM_##state: return #state + switch (state) { + MEI_HBM_STATE(IDLE); + MEI_HBM_STATE(STARTING); + MEI_HBM_STATE(STARTED); + MEI_HBM_STATE(ENUM_CLIENTS); + MEI_HBM_STATE(CLIENT_PROPERTIES); + MEI_HBM_STATE(STOPPED); + default: + return "unknown"; + } +#undef MEI_HBM_STATE +} + /** * mei_cl_conn_status_to_errno - convert client connect response * status to error code diff --git a/drivers/misc/mei/hbm.h b/drivers/misc/mei/hbm.h index 80920f096c04..efcb0d45bbe6 100644 --- a/drivers/misc/mei/hbm.h +++ b/drivers/misc/mei/hbm.h @@ -40,6 +40,8 @@ enum mei_hbm_state { MEI_HBM_STOPPED, }; +const char *mei_hbm_state_str(enum mei_hbm_state state); + int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr); static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length) diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 9f635be684ea..81695e4cf0a0 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -43,6 +43,18 @@ const char *mei_dev_state_str(int state) #undef MEI_DEV_STATE } +const char *mei_pg_state_str(enum mei_pg_state state) +{ +#define MEI_PG_STATE(state) case MEI_PG_##state: return #state + switch (state) { + MEI_PG_STATE(OFF); + MEI_PG_STATE(ON); + default: + return "unknown"; + } +#undef MEI_PG_STATE +} + /** * mei_cancel_work. Cancel mei background jobs diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 719edeeb3ceb..be7b14766cfa 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -375,6 +375,8 @@ enum mei_pg_state { MEI_PG_ON = 1, }; +const char *mei_pg_state_str(enum mei_pg_state state); + /* * mei_cfg * -- cgit v1.2.3 From c44952003fc949e81ae0a0297e91894d8724f7fe Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Mon, 29 Sep 2014 16:31:34 +0300 Subject: mei: debugfs: adjust print buffer In case of many me clients (15 and more) 1K buffer is not enough for full information print. Calculate buffer size according to real clients number. Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/debugfs.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index 2399b3181e6c..ca2a12d702a9 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c @@ -29,20 +29,28 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf, { struct mei_device *dev = fp->private_data; struct mei_me_client *me_cl; - const size_t bufsz = 1024; - char *buf = kzalloc(bufsz, GFP_KERNEL); + size_t bufsz = 1; + char *buf; int i = 0; int pos = 0; int ret; - if (!buf) - return -ENOMEM; - - pos += scnprintf(buf + pos, bufsz - pos, - " |id|addr| UUID |con|msg len|\n"); +#define HDR " |id|addr| UUID |con|msg len|\n" mutex_lock(&dev->device_lock); + list_for_each_entry(me_cl, &dev->me_clients, list) + bufsz++; + + bufsz *= sizeof(HDR) + 1; + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + mutex_unlock(&dev->device_lock); + return -ENOMEM; + } + + pos += scnprintf(buf + pos, bufsz - pos, HDR); + /* if the driver is not enabled the list won't be consistent */ if (dev->dev_state != MEI_DEV_ENABLED) goto out; -- cgit v1.2.3 From 2fbab57698051e68e59586bd20c17a1a487dfa63 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 29 Sep 2014 16:31:35 +0300 Subject: mei: debugfs: add single buffer indicator Add indication whether the client operates in single buffer mode Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/debugfs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index ca2a12d702a9..be16c4bc8304 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c @@ -35,7 +35,7 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf, int pos = 0; int ret; -#define HDR " |id|addr| UUID |con|msg len|\n" +#define HDR " |id|addr| UUID |con|msg len|sb|\n" mutex_lock(&dev->device_lock); @@ -62,12 +62,13 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf, continue; pos += scnprintf(buf + pos, bufsz - pos, - "%2d|%2d|%4d|%pUl|%3d|%7d|\n", + "%2d|%2d|%4d|%pUl|%3d|%7d|%2d|\n", i++, me_cl->client_id, me_cl->props.fixed_address, &me_cl->props.protocol_name, me_cl->props.max_number_of_connections, - me_cl->props.max_msg_length); + me_cl->props.max_msg_length, + me_cl->props.single_recv_buf); } out: mutex_unlock(&dev->device_lock); -- cgit v1.2.3 From 152de90d99ed0d6db08818d6f54d4d61df3b5dc1 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 29 Sep 2014 16:31:36 +0300 Subject: mei: pg: fix cat and paste error in comments Signed-off-by: Tomas Winkler Signed-off-by: Alexander Usyskin Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 498bd42bca25..241eae550b0c 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -457,7 +457,7 @@ static int mei_me_read_slots(struct mei_device *dev, unsigned char *buffer, } /** - * mei_me_pg_enter - write pg enter register to mei device. + * mei_me_pg_enter - write pg enter register * * @dev: the device structure */ @@ -470,7 +470,7 @@ static void mei_me_pg_enter(struct mei_device *dev) } /** - * mei_me_pg_enter - write pg enter register to mei device. + * mei_me_pg_exit - write pg exit register * * @dev: the device structure */ -- cgit v1.2.3 From 92db1555f3b9c9be257ef4070d87eb9410493cf3 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 29 Sep 2014 16:31:37 +0300 Subject: mei: fix style warning: Missing a blank line after declarations fix new style warning: Missing a blank line after declarations Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 1 + drivers/misc/mei/client.c | 1 + drivers/misc/mei/debugfs.c | 1 + drivers/misc/mei/hbm.c | 5 +++++ drivers/misc/mei/hw-me.c | 12 ++++++++++++ drivers/misc/mei/hw-txe.c | 29 +++++++++++++++++++++++++---- drivers/misc/mei/init.c | 6 ++++-- drivers/misc/mei/nfc.c | 1 + drivers/misc/mei/pci-txe.c | 1 + 9 files changed, 51 insertions(+), 6 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 4114758cd1ce..46241a6d79e7 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -130,6 +130,7 @@ struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev, struct file *file) { struct mei_cl_cb *cb; + list_for_each_entry(cb, &dev->amthif_rd_complete_list.list, list) if (cb->file_object == file) return cb; diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 449bb4564241..b7f21d47a375 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1065,6 +1065,7 @@ void mei_cl_all_disconnect(struct mei_device *dev) void mei_cl_all_wakeup(struct mei_device *dev) { struct mei_cl *cl; + list_for_each_entry(cl, &dev->file_list, link) { if (waitqueue_active(&cl->rx_wait)) { cl_dbg(dev, cl, "Waking up reading client!\n"); diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index be16c4bc8304..f15139d73f8f 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c @@ -179,6 +179,7 @@ void mei_dbgfs_deregister(struct mei_device *dev) int mei_dbgfs_register(struct mei_device *dev, const char *name) { struct dentry *dir, *f; + dir = debugfs_create_dir(name, NULL); if (!dir) return -ENOMEM; diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 3311b5c323af..24534ff1937e 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -111,6 +111,7 @@ void mei_hbm_idle(struct mei_device *dev) static void mei_me_cl_remove_all(struct mei_device *dev) { struct mei_me_client *me_cl, *next; + list_for_each_entry_safe(me_cl, next, &dev->me_clients, list) { list_del(&me_cl->list); kfree(me_cl); @@ -449,6 +450,7 @@ static int mei_hbm_stop_req(struct mei_device *dev) int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl) { const size_t len = sizeof(struct hbm_flow_control); + cl_dbg(dev, cl, "sending flow control\n"); return mei_hbm_cl_write(dev, cl, MEI_FLOW_CONTROL_CMD, len); } @@ -520,6 +522,7 @@ static void mei_hbm_cl_flow_control_res(struct mei_device *dev, int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl) { const size_t len = sizeof(struct hbm_client_connect_request); + return mei_hbm_cl_write(dev, cl, CLIENT_DISCONNECT_REQ_CMD, len); } @@ -534,6 +537,7 @@ int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl) int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl) { const size_t len = sizeof(struct hbm_client_connect_response); + return mei_hbm_cl_write(dev, cl, CLIENT_DISCONNECT_RES_CMD, len); } @@ -569,6 +573,7 @@ static void mei_hbm_cl_disconnect_res(struct mei_cl *cl, int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl) { const size_t len = sizeof(struct hbm_client_connect_request); + return mei_hbm_cl_write(dev, cl, CLIENT_CONNECT_REQ_CMD, len); } diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 241eae550b0c..56a9caa2e606 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -127,6 +127,7 @@ static void mei_me_hw_config(struct mei_device *dev) static inline enum mei_pg_state mei_me_pg_state(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); + return hw->pg_state; } @@ -139,6 +140,7 @@ static void mei_me_intr_clear(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); u32 hcsr = mei_hcsr_read(hw); + if ((hcsr & H_IS) == H_IS) mei_me_reg_write(hw, H_CSR, hcsr); } @@ -151,6 +153,7 @@ static void mei_me_intr_enable(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); u32 hcsr = mei_hcsr_read(hw); + hcsr |= H_IE; mei_hcsr_set(hw, hcsr); } @@ -164,6 +167,7 @@ static void mei_me_intr_disable(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); u32 hcsr = mei_hcsr_read(hw); + hcsr &= ~H_IE; mei_hcsr_set(hw, hcsr); } @@ -234,6 +238,7 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable) static void mei_me_host_set_ready(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); + hw->host_hw_state = mei_hcsr_read(hw); hw->host_hw_state |= H_IE | H_IG | H_RDY; mei_hcsr_set(hw, hw->host_hw_state); @@ -247,6 +252,7 @@ static void mei_me_host_set_ready(struct mei_device *dev) static bool mei_me_host_is_ready(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); + hw->host_hw_state = mei_hcsr_read(hw); return (hw->host_hw_state & H_RDY) == H_RDY; } @@ -260,6 +266,7 @@ static bool mei_me_host_is_ready(struct mei_device *dev) static bool mei_me_hw_is_ready(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); + hw->me_hw_state = mei_me_mecsr_read(hw); return (hw->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA; } @@ -283,6 +290,7 @@ static int mei_me_hw_ready_wait(struct mei_device *dev) static int mei_me_hw_start(struct mei_device *dev) { int ret = mei_me_hw_ready_wait(dev); + if (ret) return ret; dev_dbg(&dev->pdev->dev, "hw is ready\n"); @@ -390,6 +398,7 @@ static int mei_me_write_message(struct mei_device *dev, rem = length & 0x3; if (rem > 0) { u32 reg = 0; + memcpy(®, &buf[length - rem], rem); mei_me_reg_write(hw, H_CB_WW, reg); } @@ -448,6 +457,7 @@ static int mei_me_read_slots(struct mei_device *dev, unsigned char *buffer, if (buffer_length > 0) { u32 reg = mei_me_mecbrw_read(dev); + memcpy(reg_buf, ®, buffer_length); } @@ -465,6 +475,7 @@ static void mei_me_pg_enter(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); u32 reg = mei_me_reg_read(hw, H_HPG_CSR); + reg |= H_HPG_CSR_PGI; mei_me_reg_write(hw, H_HPG_CSR, reg); } @@ -732,6 +743,7 @@ static const struct mei_hw_ops mei_me_hw_ops = { static bool mei_me_fw_type_nm(struct pci_dev *pdev) { u32 reg; + pci_read_config_dword(pdev, PCI_CFG_HFS_2, ®); /* make sure that bit 9 (NM) is up and bit 10 (DM) is down */ return (reg & 0x600) == 0x200; diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index f1cd166094f2..1855b3b1ab21 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c @@ -177,6 +177,7 @@ static u32 mei_txe_aliveness_req_get(struct mei_device *dev) { struct mei_txe_hw *hw = to_txe_hw(dev); u32 reg; + reg = mei_txe_br_reg_read(hw, SICR_HOST_ALIVENESS_REQ_REG); return reg & SICR_HOST_ALIVENESS_REQ_REQUESTED; } @@ -192,6 +193,7 @@ static u32 mei_txe_aliveness_get(struct mei_device *dev) { struct mei_txe_hw *hw = to_txe_hw(dev); u32 reg; + reg = mei_txe_br_reg_read(hw, HICR_HOST_ALIVENESS_RESP_REG); return reg & HICR_HOST_ALIVENESS_RESP_ACK; } @@ -307,6 +309,7 @@ static bool mei_txe_pg_is_enabled(struct mei_device *dev) static inline enum mei_pg_state mei_txe_pg_state(struct mei_device *dev) { struct mei_txe_hw *hw = to_txe_hw(dev); + return hw->aliveness ? MEI_PG_OFF : MEI_PG_ON; } @@ -358,6 +361,7 @@ static bool mei_txe_is_input_ready(struct mei_device *dev) { struct mei_txe_hw *hw = to_txe_hw(dev); u32 status; + status = mei_txe_sec_reg_read(hw, SEC_IPC_INPUT_STATUS_REG); return !!(SEC_IPC_INPUT_STATUS_RDY & status); } @@ -370,6 +374,7 @@ static bool mei_txe_is_input_ready(struct mei_device *dev) static inline void mei_txe_intr_clear(struct mei_device *dev) { struct mei_txe_hw *hw = to_txe_hw(dev); + mei_txe_sec_reg_write_silent(hw, SEC_IPC_HOST_INT_STATUS_REG, SEC_IPC_HOST_INT_STATUS_PENDING); mei_txe_br_reg_write(hw, HISR_REG, HISR_INT_STS_MSK); @@ -384,6 +389,7 @@ static inline void mei_txe_intr_clear(struct mei_device *dev) static void mei_txe_intr_disable(struct mei_device *dev) { struct mei_txe_hw *hw = to_txe_hw(dev); + mei_txe_br_reg_write(hw, HHIER_REG, 0); mei_txe_br_reg_write(hw, HIER_REG, 0); } @@ -395,6 +401,7 @@ static void mei_txe_intr_disable(struct mei_device *dev) static void mei_txe_intr_enable(struct mei_device *dev) { struct mei_txe_hw *hw = to_txe_hw(dev); + mei_txe_br_reg_write(hw, HHIER_REG, IPC_HHIER_MSK); mei_txe_br_reg_write(hw, HIER_REG, HIER_INT_EN_MSK); } @@ -440,6 +447,7 @@ static void mei_txe_input_payload_write(struct mei_device *dev, unsigned long idx, u32 value) { struct mei_txe_hw *hw = to_txe_hw(dev); + mei_txe_sec_reg_write(hw, SEC_IPC_INPUT_PAYLOAD_REG + (idx * sizeof(u32)), value); } @@ -457,6 +465,7 @@ static u32 mei_txe_out_data_read(const struct mei_device *dev, unsigned long idx) { struct mei_txe_hw *hw = to_txe_hw(dev); + return mei_txe_br_reg_read(hw, BRIDGE_IPC_OUTPUT_PAYLOAD_REG + (idx * sizeof(u32))); } @@ -471,6 +480,7 @@ static u32 mei_txe_out_data_read(const struct mei_device *dev, static void mei_txe_readiness_set_host_rdy(struct mei_device *dev) { struct mei_txe_hw *hw = to_txe_hw(dev); + mei_txe_br_reg_write(hw, SICR_HOST_IPC_READINESS_REQ_REG, SICR_HOST_IPC_READINESS_HOST_RDY); @@ -484,6 +494,7 @@ static void mei_txe_readiness_set_host_rdy(struct mei_device *dev) static void mei_txe_readiness_clear(struct mei_device *dev) { struct mei_txe_hw *hw = to_txe_hw(dev); + mei_txe_br_reg_write(hw, SICR_HOST_IPC_READINESS_REQ_REG, SICR_HOST_IPC_READINESS_RDY_CLR); } @@ -496,6 +507,7 @@ static void mei_txe_readiness_clear(struct mei_device *dev) static u32 mei_txe_readiness_get(struct mei_device *dev) { struct mei_txe_hw *hw = to_txe_hw(dev); + return mei_txe_br_reg_read(hw, HICR_SEC_IPC_READINESS_REG); } @@ -519,6 +531,7 @@ static inline bool mei_txe_readiness_is_sec_rdy(u32 readiness) static bool mei_txe_hw_is_ready(struct mei_device *dev) { u32 readiness = mei_txe_readiness_get(dev); + return mei_txe_readiness_is_sec_rdy(readiness); } @@ -531,6 +544,7 @@ static inline bool mei_txe_host_is_ready(struct mei_device *dev) { struct mei_txe_hw *hw = to_txe_hw(dev); u32 reg = mei_txe_br_reg_read(hw, HICR_SEC_IPC_READINESS_REG); + return !!(reg & HICR_SEC_IPC_READINESS_HOST_RDY); } @@ -571,6 +585,7 @@ static void mei_txe_hw_config(struct mei_device *dev) { struct mei_txe_hw *hw = to_txe_hw(dev); + /* Doesn't change in runtime */ dev->hbuf_depth = PAYLOAD_SIZE / 4; @@ -621,6 +636,7 @@ static int mei_txe_write(struct mei_device *dev, if (!mei_txe_is_input_ready(dev)) { struct mei_fw_status fw_status; + mei_fw_status(dev, &fw_status); dev_err(&dev->pdev->dev, "Input is not ready " FW_STS_FMT "\n", FW_STS_PRM(fw_status)); @@ -635,6 +651,7 @@ static int mei_txe_write(struct mei_device *dev, rem = length & 0x3; if (rem > 0) { u32 reg = 0; + memcpy(®, &buf[length - rem], rem); mei_txe_input_payload_write(dev, i + 1, reg); } @@ -670,6 +687,7 @@ static size_t mei_txe_hbuf_max_len(const struct mei_device *dev) static int mei_txe_hbuf_empty_slots(struct mei_device *dev) { struct mei_txe_hw *hw = to_txe_hw(dev); + return hw->slots; } @@ -712,26 +730,29 @@ static int mei_txe_read(struct mei_device *dev, { struct mei_txe_hw *hw = to_txe_hw(dev); + u32 *reg_buf, reg; + u32 rem; u32 i; - u32 *reg_buf = (u32 *)buf; - u32 rem = len & 0x3; if (WARN_ON(!buf || !len)) return -EINVAL; + reg_buf = (u32 *)buf; + rem = len & 0x3; + dev_dbg(&dev->pdev->dev, "buffer-length = %lu buf[0]0x%08X\n", len, mei_txe_out_data_read(dev, 0)); for (i = 0; i < len / 4; i++) { /* skip header: index starts from 1 */ - u32 reg = mei_txe_out_data_read(dev, i + 1); + reg = mei_txe_out_data_read(dev, i + 1); dev_dbg(&dev->pdev->dev, "buf[%d] = 0x%08X\n", i, reg); *reg_buf++ = reg; } if (rem) { - u32 reg = mei_txe_out_data_read(dev, i + 1); + reg = mei_txe_out_data_read(dev, i + 1); memcpy(reg_buf, ®, rem); } diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 81695e4cf0a0..5c41f5860c89 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -88,6 +88,7 @@ int mei_reset(struct mei_device *dev) state != MEI_DEV_POWER_DOWN && state != MEI_DEV_POWER_UP) { struct mei_fw_status fw_status; + mei_fw_status(dev, &fw_status); dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s " FW_STS_FMT "\n", @@ -180,6 +181,7 @@ EXPORT_SYMBOL_GPL(mei_reset); int mei_start(struct mei_device *dev) { int ret; + mutex_lock(&dev->device_lock); /* acknowledge interrupt and stop interrupts */ @@ -344,15 +346,15 @@ EXPORT_SYMBOL_GPL(mei_write_is_idle); int mei_fw_status(struct mei_device *dev, struct mei_fw_status *fw_status) { - int i; const struct mei_fw_status *fw_src = &dev->cfg->fw_status; + int ret; + int i; if (!fw_status) return -EINVAL; fw_status->count = fw_src->count; for (i = 0; i < fw_src->count && i < MEI_FW_STATUS_MAX; i++) { - int ret; ret = pci_read_config_dword(dev->pdev, fw_src->status[i], &fw_status->status[i]); if (ret) diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c index e0e75d429fdf..2888e6fb1593 100644 --- a/drivers/misc/mei/nfc.c +++ b/drivers/misc/mei/nfc.c @@ -550,6 +550,7 @@ err: void mei_nfc_host_exit(struct mei_device *dev) { struct mei_nfc_dev *ndev = &nfc_dev; + cancel_work_sync(&ndev->init_work); } diff --git a/drivers/misc/mei/pci-txe.c b/drivers/misc/mei/pci-txe.c index 19de57368b7a..a5ce2ab98af2 100644 --- a/drivers/misc/mei/pci-txe.c +++ b/drivers/misc/mei/pci-txe.c @@ -52,6 +52,7 @@ static inline void mei_txe_unset_pm_domain(struct mei_device *dev) {} static void mei_txe_pci_iounmap(struct pci_dev *pdev, struct mei_txe_hw *hw) { int i; + for (i = SEC_BAR; i < NUM_OF_MEM_BARS; i++) { if (hw->mem_addr[i]) { pci_iounmap(pdev, hw->mem_addr[i]); -- cgit v1.2.3 From 55e43d1fc0fb8dd04ae8fc067994f00edae34941 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 29 Sep 2014 16:31:38 +0300 Subject: mei: nfc: fix style warning fix style warning: void function return statements are not generally useful Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/nfc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c index 2888e6fb1593..8cc93e4756b3 100644 --- a/drivers/misc/mei/nfc.c +++ b/drivers/misc/mei/nfc.c @@ -472,7 +472,6 @@ err: mei_nfc_free(ndev); mutex_unlock(&dev->device_lock); - return; } -- cgit v1.2.3 From 2628118b60b9d5bb4c580a1d5973a8e1d31a50f2 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 29 Sep 2014 16:31:39 +0300 Subject: mei: kill error message for allocation failure There is no need to log memory allocation errors as this is already done by the memory subsystem. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 4 +--- drivers/misc/mei/interrupt.c | 1 - drivers/misc/mei/main.c | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 46241a6d79e7..1f80873c8fe9 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -96,10 +96,8 @@ int mei_amthif_host_init(struct mei_device *dev) /* allocate storage for ME message buffer */ msg_buf = kcalloc(dev->iamthif_mtu, sizeof(unsigned char), GFP_KERNEL); - if (!msg_buf) { - dev_err(&dev->pdev->dev, "amthif: memory allocation for ME message buffer failed.\n"); + if (!msg_buf) return -ENOMEM; - } dev->iamthif_msg_buf = msg_buf; diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 1b6c14b8642e..b8d9cfee3e87 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -126,7 +126,6 @@ static int mei_cl_irq_read_msg(struct mei_device *dev, GFP_KERNEL); if (!buffer) { - cl_err(dev, cl, "allocation failed.\n"); list_del(&cb->list); return -ENOMEM; } diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index d60621ef5621..244fb6bf7463 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -377,7 +377,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, write_cb = mei_io_cb_init(cl, file); if (!write_cb) { - dev_err(&dev->pdev->dev, "write cb allocation failed\n"); rets = -ENOMEM; goto out; } -- cgit v1.2.3 From 2190fe2a3f4a4e76f6c5ebfc1070b86b34f0345c Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 29 Sep 2014 16:31:40 +0300 Subject: mei: move mei_hbm_hdr function from hbm.h the hbm.c mei_hbm_hder helper function is only used in hbm.c so there is no need to define it in a header file Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hbm.c | 16 ++++++++++++++++ drivers/misc/mei/hbm.h | 9 --------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 24534ff1937e..271c24086729 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -133,6 +133,22 @@ void mei_hbm_reset(struct mei_device *dev) mei_hbm_idle(dev); } +/** + * mei_hbm_hdr - construct hbm header + * + * @hdr: hbm header + * @length: payload length + */ + +static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length) +{ + hdr->host_addr = 0; + hdr->me_addr = 0; + hdr->length = length; + hdr->msg_complete = 1; + hdr->reserved = 0; +} + /** * mei_hbm_cl_hdr - construct client hbm header * diff --git a/drivers/misc/mei/hbm.h b/drivers/misc/mei/hbm.h index efcb0d45bbe6..b7cd3d857fd5 100644 --- a/drivers/misc/mei/hbm.h +++ b/drivers/misc/mei/hbm.h @@ -44,15 +44,6 @@ const char *mei_hbm_state_str(enum mei_hbm_state state); int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr); -static inline void mei_hbm_hdr(struct mei_msg_hdr *hdr, size_t length) -{ - hdr->host_addr = 0; - hdr->me_addr = 0; - hdr->length = length; - hdr->msg_complete = 1; - hdr->reserved = 0; -} - void mei_hbm_idle(struct mei_device *dev); void mei_hbm_reset(struct mei_device *dev); int mei_hbm_start_req(struct mei_device *dev); -- cgit v1.2.3 From 3a7e9b6c661a23429b4a106d1ffa8aa5ce6c62bb Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 29 Sep 2014 16:31:41 +0300 Subject: mei: push all standard settings into mei_device_init Setting of hw_ops and device has should be in mei_device_init. We add reference to the parent device and remove pci dependent cfg Signed-off-by: Tomas Winkler Signed-off-by: Alexander Usyskin Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me.c | 6 ++---- drivers/misc/mei/hw-txe.c | 5 ++--- drivers/misc/mei/init.c | 14 ++++++++++++-- drivers/misc/mei/mei_dev.h | 6 +++++- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 56a9caa2e606..df42b6f6e7ca 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -824,10 +824,8 @@ struct mei_device *mei_me_dev_init(struct pci_dev *pdev, if (!dev) return NULL; - mei_device_init(dev, cfg); - - dev->ops = &mei_me_hw_ops; - + mei_device_init(dev, &pdev->dev, &mei_me_hw_ops); + dev->cfg = cfg; dev->pdev = pdev; return dev; } diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index 1855b3b1ab21..fc1a51f818d0 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c @@ -1123,14 +1123,13 @@ struct mei_device *mei_txe_dev_init(struct pci_dev *pdev, if (!dev) return NULL; - mei_device_init(dev, cfg); + mei_device_init(dev, &pdev->dev, &mei_txe_hw_ops); hw = to_txe_hw(dev); init_waitqueue_head(&hw->wait_aliveness_resp); - dev->ops = &mei_txe_hw_ops; - + dev->cfg = cfg; dev->pdev = pdev; return dev; } diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 5c41f5860c89..ac659768e2b5 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -365,7 +365,16 @@ int mei_fw_status(struct mei_device *dev, struct mei_fw_status *fw_status) } EXPORT_SYMBOL_GPL(mei_fw_status); -void mei_device_init(struct mei_device *dev, const struct mei_cfg *cfg) +/** + * mei_device_init -- initialize mei_device structure + * + * @dev: the mei device + * @device: the device structure + * @hw_ops: hw operations + */ +void mei_device_init(struct mei_device *dev, + struct device *device, + const struct mei_hw_ops *hw_ops) { /* setup our list array */ INIT_LIST_HEAD(&dev->file_list); @@ -404,7 +413,8 @@ void mei_device_init(struct mei_device *dev, const struct mei_cfg *cfg) bitmap_set(dev->host_clients_map, 0, 1); dev->pg_event = MEI_PG_EVENT_IDLE; - dev->cfg = cfg; + dev->ops = hw_ops; + dev->dev = device; } EXPORT_SYMBOL_GPL(mei_device_init); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index be7b14766cfa..705143023255 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -399,6 +399,7 @@ struct mei_cfg { * struct mei_device - MEI private device struct * @pdev - pointer to pci device struct + * @dev - device on a bus * @cdev - character device * @minor - minor number allocated for device * @@ -417,6 +418,7 @@ struct mei_cfg { */ struct mei_device { struct pci_dev *pdev; /* pointer to pci device struct */ + struct device *dev; struct cdev cdev; int minor; @@ -560,7 +562,9 @@ static inline u32 mei_slots2data(int slots) /* * mei init function prototypes */ -void mei_device_init(struct mei_device *dev, const struct mei_cfg *cfg); +void mei_device_init(struct mei_device *dev, + struct device *device, + const struct mei_hw_ops *hw_ops); int mei_reset(struct mei_device *dev); int mei_start(struct mei_device *dev); int mei_restart(struct mei_device *dev); -- cgit v1.2.3 From 2bf94cabb199f73402a5ddefa4a7bf1a82aaeda5 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 29 Sep 2014 16:31:42 +0300 Subject: mei: get rid of most of the pci dependencies in mei For purpose of adding testing HW we would like to get rid of pci dependency in generic mei code This patch provides only straight forward changes FW status and prob quirks need to be handled separately Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 68 ++++++++++++++++++++++---------------------- drivers/misc/mei/bus.c | 10 +++---- drivers/misc/mei/client.c | 46 +++++++++++++++--------------- drivers/misc/mei/client.h | 4 +-- drivers/misc/mei/debugfs.c | 6 ++-- drivers/misc/mei/hbm.c | 66 +++++++++++++++++++++--------------------- drivers/misc/mei/hw-me.c | 30 +++++++++---------- drivers/misc/mei/hw-txe.c | 53 ++++++++++++++++------------------ drivers/misc/mei/init.c | 42 +++++++++++++-------------- drivers/misc/mei/interrupt.c | 44 ++++++++++++++-------------- drivers/misc/mei/main.c | 40 +++++++++++++------------- drivers/misc/mei/nfc.c | 43 +++++++++++++--------------- drivers/misc/mei/pci-me.c | 2 +- drivers/misc/mei/pci-txe.c | 2 +- drivers/misc/mei/wd.c | 34 ++++++++++------------ 15 files changed, 239 insertions(+), 251 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 1f80873c8fe9..5d47d1b36ccf 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -78,7 +78,7 @@ int mei_amthif_host_init(struct mei_device *dev) me_cl = mei_me_cl_by_uuid(dev, &mei_amthif_guid); if (!me_cl) { - dev_info(&dev->pdev->dev, "amthif: failed to find the client"); + dev_info(dev->dev, "amthif: failed to find the client"); return -ENOTTY; } @@ -88,7 +88,7 @@ int mei_amthif_host_init(struct mei_device *dev) /* Assign iamthif_mtu to the value received from ME */ dev->iamthif_mtu = me_cl->props.max_msg_length; - dev_dbg(&dev->pdev->dev, "IAMTHIF_MTU = %d\n", dev->iamthif_mtu); + dev_dbg(dev->dev, "IAMTHIF_MTU = %d\n", dev->iamthif_mtu); kfree(dev->iamthif_msg_buf); dev->iamthif_msg_buf = NULL; @@ -104,7 +104,7 @@ int mei_amthif_host_init(struct mei_device *dev) ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID); if (ret < 0) { - dev_err(&dev->pdev->dev, + dev_err(dev->dev, "amthif: failed link client %d\n", ret); return ret; } @@ -164,11 +164,11 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, /* Only possible if we are in timeout */ if (!cl) { - dev_err(&dev->pdev->dev, "bad file ext.\n"); + dev_err(dev->dev, "bad file ext.\n"); return -ETIME; } - dev_dbg(&dev->pdev->dev, "checking amthif data\n"); + dev_dbg(dev->dev, "checking amthif data\n"); cb = mei_amthif_find_read_list_entry(dev, file); /* Check for if we can block or not*/ @@ -176,7 +176,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, return -EAGAIN; - dev_dbg(&dev->pdev->dev, "waiting for amthif data\n"); + dev_dbg(dev->dev, "waiting for amthif data\n"); while (cb == NULL) { /* unlock the Mutex */ mutex_unlock(&dev->device_lock); @@ -190,21 +190,21 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, if (wait_ret) return -ERESTARTSYS; - dev_dbg(&dev->pdev->dev, "woke up from sleep\n"); + dev_dbg(dev->dev, "woke up from sleep\n"); } - dev_dbg(&dev->pdev->dev, "Got amthif data\n"); + dev_dbg(dev->dev, "Got amthif data\n"); dev->iamthif_timer = 0; if (cb) { timeout = cb->read_time + mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER); - dev_dbg(&dev->pdev->dev, "amthif timeout = %lud\n", + dev_dbg(dev->dev, "amthif timeout = %lud\n", timeout); if (time_after(jiffies, timeout)) { - dev_dbg(&dev->pdev->dev, "amthif Time out\n"); + dev_dbg(dev->dev, "amthif Time out\n"); /* 15 sec for the message has expired */ list_del(&cb->list); rets = -ETIME; @@ -224,16 +224,16 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, * remove message from deletion list */ - dev_dbg(&dev->pdev->dev, "amthif cb->response_buffer size - %d\n", + dev_dbg(dev->dev, "amthif cb->response_buffer size - %d\n", cb->response_buffer.size); - dev_dbg(&dev->pdev->dev, "amthif cb->buf_idx - %lu\n", cb->buf_idx); + dev_dbg(dev->dev, "amthif cb->buf_idx - %lu\n", cb->buf_idx); /* length is being truncated to PAGE_SIZE, however, * the buf_idx may point beyond */ length = min_t(size_t, length, (cb->buf_idx - *offset)); if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) { - dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n"); + dev_dbg(dev->dev, "failed to copy data to userland\n"); rets = -EFAULT; } else { rets = length; @@ -243,7 +243,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, } } free: - dev_dbg(&dev->pdev->dev, "free amthif cb memory.\n"); + dev_dbg(dev->dev, "free amthif cb memory.\n"); *offset = 0; mei_io_cb_free(cb); out: @@ -267,7 +267,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) if (!dev || !cb) return -ENODEV; - dev_dbg(&dev->pdev->dev, "write data to amthif client.\n"); + dev_dbg(dev->dev, "write data to amthif client.\n"); dev->iamthif_state = MEI_IAMTHIF_WRITING; dev->iamthif_current_cb = cb; @@ -306,12 +306,12 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) return -EIO; dev->iamthif_flow_control_pending = true; dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; - dev_dbg(&dev->pdev->dev, "add amthif cb to write waiting list\n"); + dev_dbg(dev->dev, "add amthif cb to write waiting list\n"); dev->iamthif_current_cb = cb; dev->iamthif_file_object = cb->file_object; list_add_tail(&cb->list, &dev->write_waiting_list.list); } else { - dev_dbg(&dev->pdev->dev, "message does not complete, so add amthif cb to write list.\n"); + dev_dbg(dev->dev, "message does not complete, so add amthif cb to write list.\n"); list_add_tail(&cb->list, &dev->write_list.list); } } else { @@ -344,9 +344,9 @@ int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb) if (!list_empty(&dev->amthif_cmd_list.list) || dev->iamthif_state != MEI_IAMTHIF_IDLE) { - dev_dbg(&dev->pdev->dev, + dev_dbg(dev->dev, "amthif state = %d\n", dev->iamthif_state); - dev_dbg(&dev->pdev->dev, "AMTHIF: add cb to the wait list\n"); + dev_dbg(dev->dev, "AMTHIF: add cb to the wait list\n"); list_add_tail(&cb->list, &dev->amthif_cmd_list.list); return 0; } @@ -376,7 +376,7 @@ void mei_amthif_run_next_cmd(struct mei_device *dev) dev->iamthif_timer = 0; dev->iamthif_file_object = NULL; - dev_dbg(&dev->pdev->dev, "complete amthif cmd_list cb.\n"); + dev_dbg(dev->dev, "complete amthif cmd_list cb.\n"); list_for_each_entry_safe(cb, next, &dev->amthif_cmd_list.list, list) { list_del(&cb->list); @@ -384,7 +384,7 @@ void mei_amthif_run_next_cmd(struct mei_device *dev) continue; status = mei_amthif_send_cmd(dev, cb); if (status) - dev_warn(&dev->pdev->dev, "amthif write failed status = %d\n", + dev_warn(dev->dev, "amthif write failed status = %d\n", status); break; } @@ -407,7 +407,7 @@ unsigned int mei_amthif_poll(struct mei_device *dev, dev->iamthif_file_object == file) { mask |= (POLLIN | POLLRDNORM); - dev_dbg(&dev->pdev->dev, "run next amthif cb\n"); + dev_dbg(dev->dev, "run next amthif cb\n"); mei_amthif_run_next_cmd(dev); } mutex_unlock(&dev->device_lock); @@ -467,7 +467,7 @@ int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, return 0; } - dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr)); + dev_dbg(dev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr)); rets = mei_write_message(dev, &mei_hdr, dev->iamthif_msg_buf + dev->iamthif_msg_buf_index); @@ -529,10 +529,10 @@ int mei_amthif_irq_read_msg(struct mei_device *dev, if (!mei_hdr->msg_complete) return 0; - dev_dbg(&dev->pdev->dev, "amthif_message_buffer_index =%d\n", + dev_dbg(dev->dev, "amthif_message_buffer_index =%d\n", mei_hdr->length); - dev_dbg(&dev->pdev->dev, "completed amthif read.\n "); + dev_dbg(dev->dev, "completed amthif read.\n "); if (!dev->iamthif_current_cb) return -ENODEV; @@ -547,8 +547,8 @@ int mei_amthif_irq_read_msg(struct mei_device *dev, cb->read_time = jiffies; if (dev->iamthif_ioctl) { /* found the iamthif cb */ - dev_dbg(&dev->pdev->dev, "complete the amthif read cb.\n "); - dev_dbg(&dev->pdev->dev, "add the amthif read cb to complete.\n "); + dev_dbg(dev->dev, "complete the amthif read cb.\n "); + dev_dbg(dev->dev, "add the amthif read cb to complete.\n "); list_add_tail(&cb->list, &complete_list->list); } return 0; @@ -572,11 +572,11 @@ int mei_amthif_irq_read(struct mei_device *dev, s32 *slots) *slots -= msg_slots; if (mei_hbm_cl_flow_control_req(dev, &dev->iamthif_cl)) { - dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n"); + dev_dbg(dev->dev, "iamthif flow control failed\n"); return -EIO; } - dev_dbg(&dev->pdev->dev, "iamthif flow control success\n"); + dev_dbg(dev->dev, "iamthif flow control success\n"); dev->iamthif_state = MEI_IAMTHIF_READING; dev->iamthif_flow_control_pending = false; dev->iamthif_msg_buf_index = 0; @@ -601,15 +601,15 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb) dev->iamthif_msg_buf, dev->iamthif_msg_buf_index); list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list); - dev_dbg(&dev->pdev->dev, "amthif read completed\n"); + dev_dbg(dev->dev, "amthif read completed\n"); dev->iamthif_timer = jiffies; - dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", + dev_dbg(dev->dev, "dev->iamthif_timer = %ld\n", dev->iamthif_timer); } else { mei_amthif_run_next_cmd(dev); } - dev_dbg(&dev->pdev->dev, "completing amthif call back.\n"); + dev_dbg(dev->dev, "completing amthif call back.\n"); wake_up_interruptible(&dev->iamthif_cl.wait); } @@ -715,11 +715,11 @@ int mei_amthif_release(struct mei_device *dev, struct file *file) if (dev->iamthif_file_object == file && dev->iamthif_state != MEI_IAMTHIF_IDLE) { - dev_dbg(&dev->pdev->dev, "amthif canceled iamthif state %d\n", + dev_dbg(dev->dev, "amthif canceled iamthif state %d\n", dev->iamthif_state); dev->iamthif_canceled = true; if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) { - dev_dbg(&dev->pdev->dev, "run next amthif iamthif cb\n"); + dev_dbg(dev->dev, "run next amthif iamthif cb\n"); mei_amthif_run_next_cmd(dev); } } diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 1cf3a72f2954..4cc1a66187be 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -172,7 +172,7 @@ struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, device->cl = cl; device->ops = ops; - device->dev.parent = &dev->pdev->dev; + device->dev.parent = dev->dev; device->dev.bus = &mei_cl_bus_type; device->dev.type = &mei_cl_device_type; @@ -180,7 +180,7 @@ struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, status = device_register(&device->dev); if (status) { - dev_err(&dev->pdev->dev, "Failed to register MEI device\n"); + dev_err(dev->dev, "Failed to register MEI device\n"); kfree(device); return NULL; } @@ -430,7 +430,7 @@ int mei_cl_enable_device(struct mei_cl_device *device) err = mei_cl_connect(cl, NULL); if (err < 0) { mutex_unlock(&dev->device_lock); - dev_err(&dev->pdev->dev, "Could not connect to the ME client"); + dev_err(dev->dev, "Could not connect to the ME client"); return err; } @@ -462,7 +462,7 @@ int mei_cl_disable_device(struct mei_cl_device *device) if (cl->state != MEI_FILE_CONNECTED) { mutex_unlock(&dev->device_lock); - dev_err(&dev->pdev->dev, "Already disconnected"); + dev_err(dev->dev, "Already disconnected"); return 0; } @@ -472,7 +472,7 @@ int mei_cl_disable_device(struct mei_cl_device *device) err = mei_cl_disconnect(cl); if (err < 0) { mutex_unlock(&dev->device_lock); - dev_err(&dev->pdev->dev, + dev_err(dev->dev, "Could not disconnect from the ME client"); return err; diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index b7f21d47a375..bfc3ad24db9c 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -363,13 +363,13 @@ int mei_cl_link(struct mei_cl *cl, int id) MEI_CLIENTS_MAX); if (id >= MEI_CLIENTS_MAX) { - dev_err(&dev->pdev->dev, "id exceeded %d", MEI_CLIENTS_MAX); + dev_err(dev->dev, "id exceeded %d", MEI_CLIENTS_MAX); return -EMFILE; } open_handle_count = dev->open_handle_count + dev->iamthif_open_count; if (open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) { - dev_err(&dev->pdev->dev, "open_handle_count exceeded %d", + dev_err(dev->dev, "open_handle_count exceeded %d", MEI_MAX_OPEN_HANDLE_COUNT); return -EMFILE; } @@ -449,9 +449,9 @@ void mei_host_client_init(struct work_struct *work) mutex_unlock(&dev->device_lock); - pm_runtime_mark_last_busy(&dev->pdev->dev); - dev_dbg(&dev->pdev->dev, "rpm: autosuspend\n"); - pm_runtime_autosuspend(&dev->pdev->dev); + pm_runtime_mark_last_busy(dev->dev); + dev_dbg(dev->dev, "rpm: autosuspend\n"); + pm_runtime_autosuspend(dev->dev); } /** @@ -464,12 +464,12 @@ bool mei_hbuf_acquire(struct mei_device *dev) { if (mei_pg_state(dev) == MEI_PG_ON || dev->pg_event == MEI_PG_EVENT_WAIT) { - dev_dbg(&dev->pdev->dev, "device is in pg\n"); + dev_dbg(dev->dev, "device is in pg\n"); return false; } if (!dev->hbuf_is_ready) { - dev_dbg(&dev->pdev->dev, "hbuf is not ready\n"); + dev_dbg(dev->dev, "hbuf is not ready\n"); return false; } @@ -503,9 +503,9 @@ int mei_cl_disconnect(struct mei_cl *cl) if (cl->state != MEI_FILE_DISCONNECTING) return 0; - rets = pm_runtime_get(&dev->pdev->dev); + rets = pm_runtime_get(dev->dev); if (rets < 0 && rets != -EINPROGRESS) { - pm_runtime_put_noidle(&dev->pdev->dev); + pm_runtime_put_noidle(dev->dev); cl_err(dev, cl, "rpm: get failed %d\n", rets); return rets; } @@ -552,8 +552,8 @@ int mei_cl_disconnect(struct mei_cl *cl) mei_io_list_flush(&dev->ctrl_wr_list, cl); free: cl_dbg(dev, cl, "rpm: autosuspend\n"); - pm_runtime_mark_last_busy(&dev->pdev->dev); - pm_runtime_put_autosuspend(&dev->pdev->dev); + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); mei_io_cb_free(cb); return rets; @@ -609,9 +609,9 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file) dev = cl->dev; - rets = pm_runtime_get(&dev->pdev->dev); + rets = pm_runtime_get(dev->dev); if (rets < 0 && rets != -EINPROGRESS) { - pm_runtime_put_noidle(&dev->pdev->dev); + pm_runtime_put_noidle(dev->dev); cl_err(dev, cl, "rpm: get failed %d\n", rets); return rets; } @@ -659,8 +659,8 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file) out: cl_dbg(dev, cl, "rpm: autosuspend\n"); - pm_runtime_mark_last_busy(&dev->pdev->dev); - pm_runtime_put_autosuspend(&dev->pdev->dev); + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); mei_io_cb_free(cb); return rets; @@ -772,9 +772,9 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) return -ENOTTY; } - rets = pm_runtime_get(&dev->pdev->dev); + rets = pm_runtime_get(dev->dev); if (rets < 0 && rets != -EINPROGRESS) { - pm_runtime_put_noidle(&dev->pdev->dev); + pm_runtime_put_noidle(dev->dev); cl_err(dev, cl, "rpm: get failed %d\n", rets); return rets; } @@ -806,8 +806,8 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) out: cl_dbg(dev, cl, "rpm: autosuspend\n"); - pm_runtime_mark_last_busy(&dev->pdev->dev); - pm_runtime_put_autosuspend(&dev->pdev->dev); + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); if (rets) mei_io_cb_free(cb); @@ -928,9 +928,9 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking) cl_dbg(dev, cl, "mei_cl_write %d\n", buf->size); - rets = pm_runtime_get(&dev->pdev->dev); + rets = pm_runtime_get(dev->dev); if (rets < 0 && rets != -EINPROGRESS) { - pm_runtime_put_noidle(&dev->pdev->dev); + pm_runtime_put_noidle(dev->dev); cl_err(dev, cl, "rpm: get failed %d\n", rets); return rets; } @@ -1005,8 +1005,8 @@ out: rets = buf->size; err: cl_dbg(dev, cl, "rpm: autosuspend\n"); - pm_runtime_mark_last_busy(&dev->pdev->dev); - pm_runtime_put_autosuspend(&dev->pdev->dev); + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); return rets; } diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index f5d03d622923..d9d0c1525259 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h @@ -110,9 +110,9 @@ void mei_cl_all_write_clear(struct mei_device *dev); #define MEI_CL_PRM(cl) (cl)->host_client_id, (cl)->me_client_id #define cl_dbg(dev, cl, format, arg...) \ - dev_dbg(&(dev)->pdev->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg) + dev_dbg((dev)->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg) #define cl_err(dev, cl, format, arg...) \ - dev_err(&(dev)->pdev->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg) + dev_err((dev)->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg) #endif /* _MEI_CLIENT_H_ */ diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index f15139d73f8f..e14a7db9a669 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c @@ -187,19 +187,19 @@ int mei_dbgfs_register(struct mei_device *dev, const char *name) f = debugfs_create_file("meclients", S_IRUSR, dir, dev, &mei_dbgfs_fops_meclients); if (!f) { - dev_err(&dev->pdev->dev, "meclients: registration failed\n"); + dev_err(dev->dev, "meclients: registration failed\n"); goto err; } f = debugfs_create_file("active", S_IRUSR, dir, dev, &mei_dbgfs_fops_active); if (!f) { - dev_err(&dev->pdev->dev, "meclients: registration failed\n"); + dev_err(dev->dev, "meclients: registration failed\n"); goto err; } f = debugfs_create_file("devstate", S_IRUSR, dir, dev, &mei_dbgfs_fops_devstate); if (!f) { - dev_err(&dev->pdev->dev, "devstate: registration failed\n"); + dev_err(dev->dev, "devstate: registration failed\n"); goto err; } dev->dbgfs_dir = dir; diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 271c24086729..209650bccf57 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -248,7 +248,7 @@ int mei_hbm_start_wait(struct mei_device *dev) if (ret == 0 && (dev->hbm_state <= MEI_HBM_STARTING)) { dev->hbm_state = MEI_HBM_IDLE; - dev_err(&dev->pdev->dev, "waiting for mei start failed\n"); + dev_err(dev->dev, "waiting for mei start failed\n"); return -ETIME; } return 0; @@ -282,7 +282,7 @@ int mei_hbm_start_req(struct mei_device *dev) dev->hbm_state = MEI_HBM_IDLE; ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); if (ret) { - dev_err(&dev->pdev->dev, "version message write failed: ret = %d\n", + dev_err(dev->dev, "version message write failed: ret = %d\n", ret); return ret; } @@ -315,7 +315,7 @@ static int mei_hbm_enum_clients_req(struct mei_device *dev) ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); if (ret) { - dev_err(&dev->pdev->dev, "enumeration request write failed: ret = %d.\n", + dev_err(dev->dev, "enumeration request write failed: ret = %d.\n", ret); return ret; } @@ -388,7 +388,7 @@ static int mei_hbm_prop_req(struct mei_device *dev) ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); if (ret) { - dev_err(&dev->pdev->dev, "properties request write failed: ret = %d\n", + dev_err(dev->dev, "properties request write failed: ret = %d\n", ret); return ret; } @@ -426,7 +426,7 @@ int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd) ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data); if (ret) - dev_err(&dev->pdev->dev, "power gate command write failed.\n"); + dev_err(dev->dev, "power gate command write failed.\n"); return ret; } EXPORT_SYMBOL_GPL(mei_hbm_pg); @@ -486,7 +486,7 @@ static int mei_hbm_add_single_flow_creds(struct mei_device *dev, me_cl = mei_me_cl_by_id(dev, flow->me_addr); if (!me_cl) { - dev_err(&dev->pdev->dev, "no such me client %d\n", + dev_err(dev->dev, "no such me client %d\n", flow->me_addr); return -ENOENT; } @@ -495,7 +495,7 @@ static int mei_hbm_add_single_flow_creds(struct mei_device *dev, return -EINVAL; me_cl->mei_flow_ctrl_creds++; - dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single) creds = %d.\n", + dev_dbg(dev->dev, "recv flow ctrl msg ME %d (single) creds = %d.\n", flow->me_addr, me_cl->mei_flow_ctrl_creds); return 0; @@ -570,7 +570,7 @@ static void mei_hbm_cl_disconnect_res(struct mei_cl *cl, struct hbm_client_connect_response *rs = (struct hbm_client_connect_response *)cmd; - dev_dbg(&cl->dev->pdev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n", + dev_dbg(cl->dev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n", rs->me_addr, rs->host_addr, rs->status); if (rs->status == MEI_CL_DISCONN_SUCCESS) @@ -606,7 +606,7 @@ static void mei_hbm_cl_connect_res(struct mei_cl *cl, struct hbm_client_connect_response *rs = (struct hbm_client_connect_response *)cmd; - dev_dbg(&cl->dev->pdev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n", + dev_dbg(cl->dev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n", rs->me_addr, rs->host_addr, mei_cl_conn_status_str(rs->status)); @@ -763,19 +763,19 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) * hbm is put to idle during system reset */ if (dev->hbm_state == MEI_HBM_IDLE) { - dev_dbg(&dev->pdev->dev, "hbm: state is idle ignore spurious messages\n"); + dev_dbg(dev->dev, "hbm: state is idle ignore spurious messages\n"); return 0; } switch (mei_msg->hbm_cmd) { case HOST_START_RES_CMD: - dev_dbg(&dev->pdev->dev, "hbm: start: response message received.\n"); + dev_dbg(dev->dev, "hbm: start: response message received.\n"); dev->init_clients_timer = 0; version_res = (struct hbm_host_version_response *)mei_msg; - dev_dbg(&dev->pdev->dev, "HBM VERSION: DRIVER=%02d:%02d DEVICE=%02d:%02d\n", + dev_dbg(dev->dev, "HBM VERSION: DRIVER=%02d:%02d DEVICE=%02d:%02d\n", HBM_MAJOR_VERSION, HBM_MINOR_VERSION, version_res->me_max_version.major_version, version_res->me_max_version.minor_version); @@ -791,11 +791,11 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) } if (!mei_hbm_version_is_supported(dev)) { - dev_warn(&dev->pdev->dev, "hbm: start: version mismatch - stopping the driver.\n"); + dev_warn(dev->dev, "hbm: start: version mismatch - stopping the driver.\n"); dev->hbm_state = MEI_HBM_STOPPED; if (mei_hbm_stop_req(dev)) { - dev_err(&dev->pdev->dev, "hbm: start: failed to send stop request\n"); + dev_err(dev->dev, "hbm: start: failed to send stop request\n"); return -EIO; } break; @@ -805,7 +805,7 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) if (dev->dev_state != MEI_DEV_INIT_CLIENTS || dev->hbm_state != MEI_HBM_STARTING) { - dev_err(&dev->pdev->dev, "hbm: start: state mismatch, [%d, %d]\n", + dev_err(dev->dev, "hbm: start: state mismatch, [%d, %d]\n", dev->dev_state, dev->hbm_state); return -EPROTO; } @@ -813,7 +813,7 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) dev->hbm_state = MEI_HBM_STARTED; if (mei_hbm_enum_clients_req(dev)) { - dev_err(&dev->pdev->dev, "hbm: start: failed to send enumeration request\n"); + dev_err(dev->dev, "hbm: start: failed to send enumeration request\n"); return -EIO; } @@ -821,31 +821,31 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) break; case CLIENT_CONNECT_RES_CMD: - dev_dbg(&dev->pdev->dev, "hbm: client connect response: message received.\n"); + dev_dbg(dev->dev, "hbm: client connect response: message received.\n"); mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_CONNECT); break; case CLIENT_DISCONNECT_RES_CMD: - dev_dbg(&dev->pdev->dev, "hbm: client disconnect response: message received.\n"); + dev_dbg(dev->dev, "hbm: client disconnect response: message received.\n"); mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_DISCONNECT); break; case MEI_FLOW_CONTROL_CMD: - dev_dbg(&dev->pdev->dev, "hbm: client flow control response: message received.\n"); + dev_dbg(dev->dev, "hbm: client flow control response: message received.\n"); flow_control = (struct hbm_flow_control *) mei_msg; mei_hbm_cl_flow_control_res(dev, flow_control); break; case MEI_PG_ISOLATION_ENTRY_RES_CMD: - dev_dbg(&dev->pdev->dev, "power gate isolation entry response received\n"); + dev_dbg(dev->dev, "power gate isolation entry response received\n"); dev->pg_event = MEI_PG_EVENT_RECEIVED; if (waitqueue_active(&dev->wait_pg)) wake_up(&dev->wait_pg); break; case MEI_PG_ISOLATION_EXIT_REQ_CMD: - dev_dbg(&dev->pdev->dev, "power gate isolation exit request received\n"); + dev_dbg(dev->dev, "power gate isolation exit request received\n"); dev->pg_event = MEI_PG_EVENT_RECEIVED; if (waitqueue_active(&dev->wait_pg)) wake_up(&dev->wait_pg); @@ -855,17 +855,17 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) * this is HW initiated exit from PG. * Start runtime pm resume sequence to exit from PG. */ - pm_request_resume(&dev->pdev->dev); + pm_request_resume(dev->dev); break; case HOST_CLIENT_PROPERTIES_RES_CMD: - dev_dbg(&dev->pdev->dev, "hbm: properties response: message received.\n"); + dev_dbg(dev->dev, "hbm: properties response: message received.\n"); dev->init_clients_timer = 0; if (dev->dev_state != MEI_DEV_INIT_CLIENTS || dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) { - dev_err(&dev->pdev->dev, "hbm: properties response: state mismatch, [%d, %d]\n", + dev_err(dev->dev, "hbm: properties response: state mismatch, [%d, %d]\n", dev->dev_state, dev->hbm_state); return -EPROTO; } @@ -873,7 +873,7 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) props_res = (struct hbm_props_response *)mei_msg; if (props_res->status) { - dev_err(&dev->pdev->dev, "hbm: properties response: wrong status = %d %s\n", + dev_err(dev->dev, "hbm: properties response: wrong status = %d %s\n", props_res->status, mei_hbm_status_str(props_res->status)); return -EPROTO; @@ -891,7 +891,7 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) break; case HOST_ENUM_RES_CMD: - dev_dbg(&dev->pdev->dev, "hbm: enumeration response: message received\n"); + dev_dbg(dev->dev, "hbm: enumeration response: message received\n"); dev->init_clients_timer = 0; @@ -903,7 +903,7 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) if (dev->dev_state != MEI_DEV_INIT_CLIENTS || dev->hbm_state != MEI_HBM_ENUM_CLIENTS) { - dev_err(&dev->pdev->dev, "hbm: enumeration response: state mismatch, [%d, %d]\n", + dev_err(dev->dev, "hbm: enumeration response: state mismatch, [%d, %d]\n", dev->dev_state, dev->hbm_state); return -EPROTO; } @@ -917,34 +917,34 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) break; case HOST_STOP_RES_CMD: - dev_dbg(&dev->pdev->dev, "hbm: stop response: message received\n"); + dev_dbg(dev->dev, "hbm: stop response: message received\n"); dev->init_clients_timer = 0; if (dev->hbm_state != MEI_HBM_STOPPED) { - dev_err(&dev->pdev->dev, "hbm: stop response: state mismatch, [%d, %d]\n", + dev_err(dev->dev, "hbm: stop response: state mismatch, [%d, %d]\n", dev->dev_state, dev->hbm_state); return -EPROTO; } dev->dev_state = MEI_DEV_POWER_DOWN; - dev_info(&dev->pdev->dev, "hbm: stop response: resetting.\n"); + dev_info(dev->dev, "hbm: stop response: resetting.\n"); /* force the reset */ return -EPROTO; break; case CLIENT_DISCONNECT_REQ_CMD: - dev_dbg(&dev->pdev->dev, "hbm: disconnect request: message received\n"); + dev_dbg(dev->dev, "hbm: disconnect request: message received\n"); disconnect_req = (struct hbm_client_connect_request *)mei_msg; mei_hbm_fw_disconnect_req(dev, disconnect_req); break; case ME_STOP_REQ_CMD: - dev_dbg(&dev->pdev->dev, "hbm: stop request: message received\n"); + dev_dbg(dev->dev, "hbm: stop request: message received\n"); dev->hbm_state = MEI_HBM_STOPPED; if (mei_hbm_stop_req(dev)) { - dev_err(&dev->pdev->dev, "hbm: stop request: failed to send stop request\n"); + dev_err(dev->dev, "hbm: stop request: failed to send stop request\n"); return -EIO; } break; diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index df42b6f6e7ca..1247be706216 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -217,10 +217,10 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable) hcsr = mei_hcsr_read(hw); if ((hcsr & H_RST) == 0) - dev_warn(&dev->pdev->dev, "H_RST is not set = 0x%08X", hcsr); + dev_warn(dev->dev, "H_RST is not set = 0x%08X", hcsr); if ((hcsr & H_RDY) == H_RDY) - dev_warn(&dev->pdev->dev, "H_RDY is not cleared 0x%08X", hcsr); + dev_warn(dev->dev, "H_RDY is not cleared 0x%08X", hcsr); if (intr_enable == false) mei_me_hw_reset_release(dev); @@ -279,7 +279,7 @@ static int mei_me_hw_ready_wait(struct mei_device *dev) mei_secs_to_jiffies(MEI_HW_READY_TIMEOUT)); mutex_lock(&dev->device_lock); if (!dev->recvd_hw_ready) { - dev_err(&dev->pdev->dev, "wait hw ready failed\n"); + dev_err(dev->dev, "wait hw ready failed\n"); return -ETIME; } @@ -293,7 +293,7 @@ static int mei_me_hw_start(struct mei_device *dev) if (ret) return ret; - dev_dbg(&dev->pdev->dev, "hw is ready\n"); + dev_dbg(dev->dev, "hw is ready\n"); mei_me_host_set_ready(dev); return ret; @@ -381,10 +381,10 @@ static int mei_me_write_message(struct mei_device *dev, int i; int empty_slots; - dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(header)); + dev_dbg(dev->dev, MEI_HDR_FMT, MEI_HDR_PRM(header)); empty_slots = mei_hbuf_empty_slots(dev); - dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots); + dev_dbg(dev->dev, "empty slots = %hu.\n", empty_slots); dw_cnt = mei_data2slots(length); if (empty_slots < 0 || dw_cnt > empty_slots) @@ -434,7 +434,7 @@ static int mei_me_count_full_read_slots(struct mei_device *dev) if (filled_slots > buffer_depth) return -EOVERFLOW; - dev_dbg(&dev->pdev->dev, "filled_slots =%08x\n", filled_slots); + dev_dbg(dev->dev, "filled_slots =%08x\n", filled_slots); return (int)filled_slots; } @@ -591,7 +591,7 @@ static bool mei_me_pg_is_enabled(struct mei_device *dev) return true; notsupported: - dev_dbg(&dev->pdev->dev, "pg: not supported: HGP = %d hbm version %d.%d ?= %d.%d\n", + dev_dbg(dev->dev, "pg: not supported: HGP = %d hbm version %d.%d ?= %d.%d\n", !!(reg & ME_PGIC_HRA), dev->version.major_version, dev->version.minor_version, @@ -642,7 +642,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) s32 slots; int rets = 0; - dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n"); + dev_dbg(dev->dev, "function called after ISR to handle the interrupt processing.\n"); /* initialize our complete list */ mutex_lock(&dev->device_lock); mei_io_list_init(&complete_list); @@ -654,7 +654,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) /* check if ME wants a reset */ if (!mei_hw_is_ready(dev) && dev->dev_state != MEI_DEV_RESETTING) { - dev_warn(&dev->pdev->dev, "FW not ready: resetting.\n"); + dev_warn(dev->dev, "FW not ready: resetting.\n"); schedule_work(&dev->reset_work); goto end; } @@ -663,19 +663,19 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) if (!mei_host_is_ready(dev)) { if (mei_hw_is_ready(dev)) { mei_me_hw_reset_release(dev); - dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); + dev_dbg(dev->dev, "we need to start the dev.\n"); dev->recvd_hw_ready = true; wake_up(&dev->wait_hw_ready); } else { - dev_dbg(&dev->pdev->dev, "Spurious Interrupt\n"); + dev_dbg(dev->dev, "Spurious Interrupt\n"); } goto end; } /* check slots available for reading */ slots = mei_count_full_read_slots(dev); while (slots > 0) { - dev_dbg(&dev->pdev->dev, "slots to read = %08x\n", slots); + dev_dbg(dev->dev, "slots to read = %08x\n", slots); rets = mei_irq_read_handler(dev, &complete_list, &slots); /* There is a race between ME write and interrupt delivery: * Not all data is always available immediately after the @@ -685,7 +685,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) break; if (rets && dev->dev_state != MEI_DEV_RESETTING) { - dev_err(&dev->pdev->dev, "mei_irq_read_handler ret = %d.\n", + dev_err(dev->dev, "mei_irq_read_handler ret = %d.\n", rets); schedule_work(&dev->reset_work); goto end; @@ -707,7 +707,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) mei_irq_compl_handler(dev, &complete_list); end: - dev_dbg(&dev->pdev->dev, "interrupt thread end ret = %d\n", rets); + dev_dbg(dev->dev, "interrupt thread end ret = %d\n", rets); mutex_unlock(&dev->device_lock); return IRQ_HANDLED; } diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index fc1a51f818d0..acc475eec150 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c @@ -155,7 +155,7 @@ static bool mei_txe_aliveness_set(struct mei_device *dev, u32 req) struct mei_txe_hw *hw = to_txe_hw(dev); bool do_req = hw->aliveness != req; - dev_dbg(&dev->pdev->dev, "Aliveness current=%d request=%d\n", + dev_dbg(dev->dev, "Aliveness current=%d request=%d\n", hw->aliveness, req); if (do_req) { dev->pg_event = MEI_PG_EVENT_WAIT; @@ -216,7 +216,7 @@ static int mei_txe_aliveness_poll(struct mei_device *dev, u32 expected) hw->aliveness = mei_txe_aliveness_get(dev); if (hw->aliveness == expected) { dev->pg_event = MEI_PG_EVENT_IDLE; - dev_dbg(&dev->pdev->dev, + dev_dbg(dev->dev, "aliveness settled after %d msecs\n", t); return t; } @@ -227,7 +227,7 @@ static int mei_txe_aliveness_poll(struct mei_device *dev, u32 expected) } while (t < SEC_ALIVENESS_WAIT_TIMEOUT); dev->pg_event = MEI_PG_EVENT_IDLE; - dev_err(&dev->pdev->dev, "aliveness timed out\n"); + dev_err(dev->dev, "aliveness timed out\n"); return -ETIME; } @@ -261,10 +261,10 @@ static int mei_txe_aliveness_wait(struct mei_device *dev, u32 expected) ret = hw->aliveness == expected ? 0 : -ETIME; if (ret) - dev_warn(&dev->pdev->dev, "aliveness timed out = %ld aliveness = %d event = %d\n", + dev_warn(dev->dev, "aliveness timed out = %ld aliveness = %d event = %d\n", err, hw->aliveness, dev->pg_event); else - dev_dbg(&dev->pdev->dev, "aliveness settled after = %d msec aliveness = %d event = %d\n", + dev_dbg(dev->dev, "aliveness settled after = %d msec aliveness = %d event = %d\n", jiffies_to_msecs(timeout - err), hw->aliveness, dev->pg_event); @@ -425,7 +425,7 @@ static bool mei_txe_pending_interrupts(struct mei_device *dev) TXE_INTR_OUT_DB)); if (ret) { - dev_dbg(&dev->pdev->dev, + dev_dbg(dev->dev, "Pending Interrupts InReady=%01d Readiness=%01d, Aliveness=%01d, OutDoor=%01d\n", !!(hw->intr_cause & TXE_INTR_IN_READY), !!(hw->intr_cause & TXE_INTR_READINESS), @@ -565,7 +565,7 @@ static int mei_txe_readiness_wait(struct mei_device *dev) msecs_to_jiffies(SEC_RESET_WAIT_TIMEOUT)); mutex_lock(&dev->device_lock); if (!dev->recvd_hw_ready) { - dev_err(&dev->pdev->dev, "wait for readiness failed\n"); + dev_err(dev->dev, "wait for readiness failed\n"); return -ETIME; } @@ -592,7 +592,7 @@ static void mei_txe_hw_config(struct mei_device *dev) hw->aliveness = mei_txe_aliveness_get(dev); hw->readiness = mei_txe_readiness_get(dev); - dev_dbg(&dev->pdev->dev, "aliveness_resp = 0x%08x, readiness = 0x%08x.\n", + dev_dbg(dev->dev, "aliveness_resp = 0x%08x, readiness = 0x%08x.\n", hw->aliveness, hw->readiness); } @@ -622,7 +622,7 @@ static int mei_txe_write(struct mei_device *dev, length = header->length; - dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(header)); + dev_dbg(dev->dev, MEI_HDR_FMT, MEI_HDR_PRM(header)); dw_cnt = mei_data2slots(length); if (dw_cnt > slots) @@ -638,7 +638,7 @@ static int mei_txe_write(struct mei_device *dev, struct mei_fw_status fw_status; mei_fw_status(dev, &fw_status); - dev_err(&dev->pdev->dev, "Input is not ready " FW_STS_FMT "\n", + dev_err(dev->dev, "Input is not ready " FW_STS_FMT "\n", FW_STS_PRM(fw_status)); return -EAGAIN; } @@ -740,14 +740,13 @@ static int mei_txe_read(struct mei_device *dev, reg_buf = (u32 *)buf; rem = len & 0x3; - dev_dbg(&dev->pdev->dev, - "buffer-length = %lu buf[0]0x%08X\n", + dev_dbg(dev->dev, "buffer-length = %lu buf[0]0x%08X\n", len, mei_txe_out_data_read(dev, 0)); for (i = 0; i < len / 4; i++) { /* skip header: index starts from 1 */ reg = mei_txe_out_data_read(dev, i + 1); - dev_dbg(&dev->pdev->dev, "buf[%d] = 0x%08X\n", i, reg); + dev_dbg(dev->dev, "buf[%d] = 0x%08X\n", i, reg); *reg_buf++ = reg; } @@ -792,8 +791,7 @@ static int mei_txe_hw_reset(struct mei_device *dev, bool intr_enable) */ if (aliveness_req != hw->aliveness) if (mei_txe_aliveness_poll(dev, aliveness_req) < 0) { - dev_err(&dev->pdev->dev, - "wait for aliveness settle failed ... bailing out\n"); + dev_err(dev->dev, "wait for aliveness settle failed ... bailing out\n"); return -EIO; } @@ -803,8 +801,7 @@ static int mei_txe_hw_reset(struct mei_device *dev, bool intr_enable) if (aliveness_req) { mei_txe_aliveness_set(dev, 0); if (mei_txe_aliveness_poll(dev, 0) < 0) { - dev_err(&dev->pdev->dev, - "wait for aliveness failed ... bailing out\n"); + dev_err(dev->dev, "wait for aliveness failed ... bailing out\n"); return -EIO; } } @@ -836,7 +833,7 @@ static int mei_txe_hw_start(struct mei_device *dev) ret = mei_txe_readiness_wait(dev); if (ret < 0) { - dev_err(&dev->pdev->dev, "wating for readiness failed\n"); + dev_err(dev->dev, "wating for readiness failed\n"); return ret; } @@ -852,7 +849,7 @@ static int mei_txe_hw_start(struct mei_device *dev) ret = mei_txe_aliveness_set_sync(dev, 1); if (ret < 0) { - dev_err(&dev->pdev->dev, "wait for aliveness failed ... bailing out\n"); + dev_err(dev->dev, "wait for aliveness failed ... bailing out\n"); return ret; } @@ -962,7 +959,7 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id) s32 slots; int rets = 0; - dev_dbg(&dev->pdev->dev, "irq thread: Interrupt Registers HHISR|HISR|SEC=%02X|%04X|%02X\n", + dev_dbg(dev->dev, "irq thread: Interrupt Registers HHISR|HISR|SEC=%02X|%04X|%02X\n", mei_txe_br_reg_read(hw, HHISR_REG), mei_txe_br_reg_read(hw, HISR_REG), mei_txe_sec_reg_read_silent(hw, SEC_IPC_HOST_INT_STATUS_REG)); @@ -986,17 +983,17 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id) * or TXE driver resetting the HECI interface. */ if (test_and_clear_bit(TXE_INTR_READINESS_BIT, &hw->intr_cause)) { - dev_dbg(&dev->pdev->dev, "Readiness Interrupt was received...\n"); + dev_dbg(dev->dev, "Readiness Interrupt was received...\n"); /* Check if SeC is going through reset */ if (mei_txe_readiness_is_sec_rdy(hw->readiness)) { - dev_dbg(&dev->pdev->dev, "we need to start the dev.\n"); + dev_dbg(dev->dev, "we need to start the dev.\n"); dev->recvd_hw_ready = true; } else { dev->recvd_hw_ready = false; if (dev->dev_state != MEI_DEV_RESETTING) { - dev_warn(&dev->pdev->dev, "FW not ready: resetting.\n"); + dev_warn(dev->dev, "FW not ready: resetting.\n"); schedule_work(&dev->reset_work); goto end; @@ -1013,7 +1010,7 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id) if (test_and_clear_bit(TXE_INTR_ALIVENESS_BIT, &hw->intr_cause)) { /* Clear the interrupt cause */ - dev_dbg(&dev->pdev->dev, + dev_dbg(dev->dev, "Aliveness Interrupt: Status: %d\n", hw->aliveness); dev->pg_event = MEI_PG_EVENT_RECEIVED; if (waitqueue_active(&hw->wait_aliveness_resp)) @@ -1029,7 +1026,7 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id) /* Read from TXE */ rets = mei_irq_read_handler(dev, &complete_list, &slots); if (rets && dev->dev_state != MEI_DEV_RESETTING) { - dev_err(&dev->pdev->dev, + dev_err(dev->dev, "mei_irq_read_handler ret = %d.\n", rets); schedule_work(&dev->reset_work); @@ -1047,7 +1044,7 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id) dev->hbuf_is_ready = mei_hbuf_is_ready(dev); rets = mei_irq_write_handler(dev, &complete_list); if (rets && rets != -EMSGSIZE) - dev_err(&dev->pdev->dev, "mei_irq_write_handler ret = %d.\n", + dev_err(dev->dev, "mei_irq_write_handler ret = %d.\n", rets); dev->hbuf_is_ready = mei_hbuf_is_ready(dev); } @@ -1055,7 +1052,7 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id) mei_irq_compl_handler(dev, &complete_list); end: - dev_dbg(&dev->pdev->dev, "interrupt thread end ret = %d\n", rets); + dev_dbg(dev->dev, "interrupt thread end ret = %d\n", rets); mutex_unlock(&dev->device_lock); @@ -1171,7 +1168,7 @@ int mei_txe_setup_satt2(struct mei_device *dev, phys_addr_t addr, u32 range) mei_txe_br_reg_write(hw, SATT2_SAP_SIZE_REG, range); mei_txe_br_reg_write(hw, SATT2_BRG_BA_LSB_REG, lo32); mei_txe_br_reg_write(hw, SATT2_CTRL_REG, ctrl); - dev_dbg(&dev->pdev->dev, "SATT2: SAP_SIZE_OFFSET=0x%08X, BRG_BA_LSB_OFFSET=0x%08X, CTRL_OFFSET=0x%08X\n", + dev_dbg(dev->dev, "SATT2: SAP_SIZE_OFFSET=0x%08X, BRG_BA_LSB_OFFSET=0x%08X, CTRL_OFFSET=0x%08X\n", range, lo32, ctrl); return 0; diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index ac659768e2b5..29aae7b7a304 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -90,7 +90,7 @@ int mei_reset(struct mei_device *dev) struct mei_fw_status fw_status; mei_fw_status(dev, &fw_status); - dev_warn(&dev->pdev->dev, + dev_warn(dev->dev, "unexpected reset: dev_state = %s " FW_STS_FMT "\n", mei_dev_state_str(state), FW_STS_PRM(fw_status)); } @@ -108,7 +108,7 @@ int mei_reset(struct mei_device *dev) dev->reset_count++; if (dev->reset_count > MEI_MAX_CONSEC_RESET) { - dev_err(&dev->pdev->dev, "reset: reached maximal consecutive resets: disabling the device\n"); + dev_err(dev->dev, "reset: reached maximal consecutive resets: disabling the device\n"); dev->dev_state = MEI_DEV_DISABLED; return -ENODEV; } @@ -129,7 +129,7 @@ int mei_reset(struct mei_device *dev) mei_cl_all_wakeup(dev); /* remove entry if already in list */ - dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n"); + dev_dbg(dev->dev, "remove iamthif and wd from the file list.\n"); mei_cl_unlink(&dev->wd_cl); mei_cl_unlink(&dev->iamthif_cl); mei_amthif_reset_params(dev); @@ -141,28 +141,28 @@ int mei_reset(struct mei_device *dev) dev->wd_pending = false; if (ret) { - dev_err(&dev->pdev->dev, "hw_reset failed ret = %d\n", ret); + dev_err(dev->dev, "hw_reset failed ret = %d\n", ret); return ret; } if (state == MEI_DEV_POWER_DOWN) { - dev_dbg(&dev->pdev->dev, "powering down: end of reset\n"); + dev_dbg(dev->dev, "powering down: end of reset\n"); dev->dev_state = MEI_DEV_DISABLED; return 0; } ret = mei_hw_start(dev); if (ret) { - dev_err(&dev->pdev->dev, "hw_start failed ret = %d\n", ret); + dev_err(dev->dev, "hw_start failed ret = %d\n", ret); return ret; } - dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n"); + dev_dbg(dev->dev, "link is established start sending messages.\n"); dev->dev_state = MEI_DEV_INIT_CLIENTS; ret = mei_hbm_start_req(dev); if (ret) { - dev_err(&dev->pdev->dev, "hbm_start failed ret = %d\n", ret); + dev_err(dev->dev, "hbm_start failed ret = %d\n", ret); dev->dev_state = MEI_DEV_RESETTING; return ret; } @@ -189,7 +189,7 @@ int mei_start(struct mei_device *dev) mei_hw_config(dev); - dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); + dev_dbg(dev->dev, "reset in start the mei device.\n"); dev->reset_count = 0; do { @@ -197,43 +197,43 @@ int mei_start(struct mei_device *dev) ret = mei_reset(dev); if (ret == -ENODEV || dev->dev_state == MEI_DEV_DISABLED) { - dev_err(&dev->pdev->dev, "reset failed ret = %d", ret); + dev_err(dev->dev, "reset failed ret = %d", ret); goto err; } } while (ret); /* we cannot start the device w/o hbm start message completed */ if (dev->dev_state == MEI_DEV_DISABLED) { - dev_err(&dev->pdev->dev, "reset failed"); + dev_err(dev->dev, "reset failed"); goto err; } if (mei_hbm_start_wait(dev)) { - dev_err(&dev->pdev->dev, "HBM haven't started"); + dev_err(dev->dev, "HBM haven't started"); goto err; } if (!mei_host_is_ready(dev)) { - dev_err(&dev->pdev->dev, "host is not ready.\n"); + dev_err(dev->dev, "host is not ready.\n"); goto err; } if (!mei_hw_is_ready(dev)) { - dev_err(&dev->pdev->dev, "ME is not ready.\n"); + dev_err(dev->dev, "ME is not ready.\n"); goto err; } if (!mei_hbm_version_is_supported(dev)) { - dev_dbg(&dev->pdev->dev, "MEI start failed.\n"); + dev_dbg(dev->dev, "MEI start failed.\n"); goto err; } - dev_dbg(&dev->pdev->dev, "link layer has been established.\n"); + dev_dbg(dev->dev, "link layer has been established.\n"); mutex_unlock(&dev->device_lock); return 0; err: - dev_err(&dev->pdev->dev, "link layer initialization failed.\n"); + dev_err(dev->dev, "link layer initialization failed.\n"); dev->dev_state = MEI_DEV_DISABLED; mutex_unlock(&dev->device_lock); return -ENODEV; @@ -263,7 +263,7 @@ int mei_restart(struct mei_device *dev) mutex_unlock(&dev->device_lock); if (err == -ENODEV || dev->dev_state == MEI_DEV_DISABLED) { - dev_err(&dev->pdev->dev, "device disabled = %d\n", err); + dev_err(dev->dev, "device disabled = %d\n", err); return -ENODEV; } @@ -289,7 +289,7 @@ static void mei_reset_work(struct work_struct *work) mutex_unlock(&dev->device_lock); if (dev->dev_state == MEI_DEV_DISABLED) { - dev_err(&dev->pdev->dev, "device disabled = %d\n", ret); + dev_err(dev->dev, "device disabled = %d\n", ret); return; } @@ -300,7 +300,7 @@ static void mei_reset_work(struct work_struct *work) void mei_stop(struct mei_device *dev) { - dev_dbg(&dev->pdev->dev, "stopping the device.\n"); + dev_dbg(dev->dev, "stopping the device.\n"); mei_cancel_work(dev); @@ -334,7 +334,7 @@ bool mei_write_is_idle(struct mei_device *dev) list_empty(&dev->ctrl_wr_list.list) && list_empty(&dev->write_list.list)); - dev_dbg(&dev->pdev->dev, "write pg: is idle[%d] state=%s ctrl=%d write=%d\n", + dev_dbg(dev->dev, "write pg: is idle[%d] state=%s ctrl=%d write=%d\n", idle, mei_dev_state_str(dev->dev_state), list_empty(&dev->ctrl_wr_list.list), diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index b8d9cfee3e87..8dac76901130 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -47,7 +47,7 @@ void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *compl_list) if (!cl) continue; - dev_dbg(&dev->pdev->dev, "completing call back.\n"); + dev_dbg(dev->dev, "completing call back.\n"); if (cl == &dev->iamthif_cl) mei_amthif_complete(dev, cb); else @@ -148,10 +148,10 @@ static int mei_cl_irq_read_msg(struct mei_device *dev, break; } - dev_dbg(&dev->pdev->dev, "message read\n"); + dev_dbg(dev->dev, "message read\n"); if (!buffer) { mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length); - dev_dbg(&dev->pdev->dev, "discarding message " MEI_HDR_FMT "\n", + dev_dbg(dev->dev, "discarding message " MEI_HDR_FMT "\n", MEI_HDR_PRM(mei_hdr)); } @@ -333,20 +333,20 @@ int mei_irq_read_handler(struct mei_device *dev, if (!dev->rd_msg_hdr) { dev->rd_msg_hdr = mei_read_hdr(dev); (*slots)--; - dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots); + dev_dbg(dev->dev, "slots =%08x.\n", *slots); } mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr; - dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); + dev_dbg(dev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); if (mei_hdr->reserved || !dev->rd_msg_hdr) { - dev_err(&dev->pdev->dev, "corrupted message header 0x%08X\n", + dev_err(dev->dev, "corrupted message header 0x%08X\n", dev->rd_msg_hdr); ret = -EBADMSG; goto end; } if (mei_slots2data(*slots) < mei_hdr->length) { - dev_err(&dev->pdev->dev, "less data available than length=%08x.\n", + dev_err(dev->dev, "less data available than length=%08x.\n", *slots); /* we can't read the message */ ret = -ENODATA; @@ -357,7 +357,7 @@ int mei_irq_read_handler(struct mei_device *dev, if (mei_hdr->host_addr == 0 && mei_hdr->me_addr == 0) { ret = mei_hbm_dispatch(dev, mei_hdr); if (ret) { - dev_dbg(&dev->pdev->dev, "mei_hbm_dispatch failed ret = %d\n", + dev_dbg(dev->dev, "mei_hbm_dispatch failed ret = %d\n", ret); goto end; } @@ -374,7 +374,7 @@ int mei_irq_read_handler(struct mei_device *dev, /* if no recipient cl was found we assume corrupted header */ if (&cl->link == &dev->file_list) { - dev_err(&dev->pdev->dev, "no destination client found 0x%08X\n", + dev_err(dev->dev, "no destination client found 0x%08X\n", dev->rd_msg_hdr); ret = -EBADMSG; goto end; @@ -386,14 +386,14 @@ int mei_irq_read_handler(struct mei_device *dev, ret = mei_amthif_irq_read_msg(dev, mei_hdr, cmpl_list); if (ret) { - dev_err(&dev->pdev->dev, "mei_amthif_irq_read_msg failed = %d\n", + dev_err(dev->dev, "mei_amthif_irq_read_msg failed = %d\n", ret); goto end; } } else { ret = mei_cl_irq_read_msg(dev, mei_hdr, cmpl_list); if (ret) { - dev_err(&dev->pdev->dev, "mei_cl_irq_read_msg failed = %d\n", + dev_err(dev->dev, "mei_cl_irq_read_msg failed = %d\n", ret); goto end; } @@ -406,7 +406,7 @@ reset_slots: if (*slots == -EOVERFLOW) { /* overflow - reset */ - dev_err(&dev->pdev->dev, "resetting due to slots overflow.\n"); + dev_err(dev->dev, "resetting due to slots overflow.\n"); /* set the event since message has been read */ ret = -ERANGE; goto end; @@ -444,7 +444,7 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) return -EMSGSIZE; /* complete all waiting for write CB */ - dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n"); + dev_dbg(dev->dev, "complete all waiting for write cb.\n"); list = &dev->write_waiting_list; list_for_each_entry_safe(cb, next, &list->list, list) { @@ -486,7 +486,7 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) } /* complete control write list CB */ - dev_dbg(&dev->pdev->dev, "complete control write list cb.\n"); + dev_dbg(dev->dev, "complete control write list cb.\n"); list_for_each_entry_safe(cb, next, &dev->ctrl_wr_list.list, list) { cl = cb->cl; if (!cl) { @@ -527,7 +527,7 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) } /* complete write list CB */ - dev_dbg(&dev->pdev->dev, "complete write list cb.\n"); + dev_dbg(dev->dev, "complete write list cb.\n"); list_for_each_entry_safe(cb, next, &dev->write_list.list, list) { cl = cb->cl; if (cl == NULL) @@ -568,7 +568,7 @@ void mei_timer(struct work_struct *work) if (dev->init_clients_timer) { if (--dev->init_clients_timer == 0) { - dev_err(&dev->pdev->dev, "timer: init clients timeout hbm_state = %d.\n", + dev_err(dev->dev, "timer: init clients timeout hbm_state = %d.\n", dev->hbm_state); mei_reset(dev); goto out; @@ -583,7 +583,7 @@ void mei_timer(struct work_struct *work) list_for_each_entry(cl, &dev->file_list, link) { if (cl->timer_count) { if (--cl->timer_count == 0) { - dev_err(&dev->pdev->dev, "timer: connect/disconnect timeout.\n"); + dev_err(dev->dev, "timer: connect/disconnect timeout.\n"); mei_reset(dev); goto out; } @@ -595,7 +595,7 @@ void mei_timer(struct work_struct *work) if (dev->iamthif_stall_timer) { if (--dev->iamthif_stall_timer == 0) { - dev_err(&dev->pdev->dev, "timer: amthif hanged.\n"); + dev_err(dev->dev, "timer: amthif hanged.\n"); mei_reset(dev); dev->iamthif_msg_buf_size = 0; dev->iamthif_msg_buf_index = 0; @@ -617,17 +617,17 @@ void mei_timer(struct work_struct *work) timeout = dev->iamthif_timer + mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER); - dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", + dev_dbg(dev->dev, "dev->iamthif_timer = %ld\n", dev->iamthif_timer); - dev_dbg(&dev->pdev->dev, "timeout = %ld\n", timeout); - dev_dbg(&dev->pdev->dev, "jiffies = %ld\n", jiffies); + dev_dbg(dev->dev, "timeout = %ld\n", timeout); + dev_dbg(dev->dev, "jiffies = %ld\n", jiffies); if (time_after(jiffies, timeout)) { /* * User didn't read the AMTHI data on time (15sec) * freeing AMTHI for other requests */ - dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n"); + dev_dbg(dev->dev, "freeing AMTHI for other requests\n"); mei_io_list_flush(&dev->amthif_rd_complete_list, &dev->iamthif_cl); diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 244fb6bf7463..4d738c881878 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -63,7 +63,7 @@ static int mei_open(struct inode *inode, struct file *file) err = -ENODEV; if (dev->dev_state != MEI_DEV_ENABLED) { - dev_dbg(&dev->pdev->dev, "dev_state != MEI_ENABLED dev_state = %s\n", + dev_dbg(dev->dev, "dev_state != MEI_ENABLED dev_state = %s\n", mei_dev_state_str(dev->dev_state)); goto err_unlock; } @@ -211,7 +211,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, err = mei_cl_read_start(cl, length); if (err && err != -EBUSY) { - dev_dbg(&dev->pdev->dev, + dev_dbg(dev->dev, "mei start read failure with status = %d\n", err); rets = err; goto out; @@ -254,7 +254,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, } /* now copy the data to user space */ copy_buffer: - dev_dbg(&dev->pdev->dev, "buf.size = %d buf.idx= %ld\n", + dev_dbg(dev->dev, "buf.size = %d buf.idx= %ld\n", cb->response_buffer.size, cb->buf_idx); if (length == 0 || ubuf == NULL || *offset > cb->buf_idx) { rets = -EMSGSIZE; @@ -266,7 +266,7 @@ copy_buffer: length = min_t(size_t, length, cb->buf_idx - *offset); if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) { - dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n"); + dev_dbg(dev->dev, "failed to copy data to userland\n"); rets = -EFAULT; goto free; } @@ -285,7 +285,7 @@ free: cl->reading_state = MEI_IDLE; cl->read_cb = NULL; out: - dev_dbg(&dev->pdev->dev, "end mei read rets= %d\n", rets); + dev_dbg(dev->dev, "end mei read rets= %d\n", rets); mutex_unlock(&dev->device_lock); return rets; } @@ -338,7 +338,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, } if (cl->state != MEI_FILE_CONNECTED) { - dev_err(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d", + dev_err(dev->dev, "host client = %d, is not connected to ME client = %d", cl->host_client_id, cl->me_client_id); rets = -ENODEV; goto out; @@ -386,7 +386,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, rets = copy_from_user(write_cb->request_buffer.data, ubuf, length); if (rets) { - dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n"); + dev_dbg(dev->dev, "failed to copy data from userland\n"); rets = -EFAULT; goto out; } @@ -395,7 +395,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, rets = mei_amthif_write(dev, write_cb); if (rets) { - dev_err(&dev->pdev->dev, + dev_err(dev->dev, "amthif write failed with status = %d\n", rets); goto out; } @@ -448,7 +448,7 @@ static int mei_ioctl_connect_client(struct file *file, /* find ME client we're trying to connect to */ me_cl = mei_me_cl_by_uuid(dev, &data->in_client_uuid); if (!me_cl || me_cl->props.fixed_address) { - dev_dbg(&dev->pdev->dev, "Cannot connect to FW Client UUID = %pUl\n", + dev_dbg(dev->dev, "Cannot connect to FW Client UUID = %pUl\n", &data->in_client_uuid); rets = -ENOTTY; goto end; @@ -457,18 +457,18 @@ static int mei_ioctl_connect_client(struct file *file, cl->me_client_id = me_cl->client_id; cl->cl_uuid = me_cl->props.protocol_name; - dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n", + dev_dbg(dev->dev, "Connect to FW Client ID = %d\n", cl->me_client_id); - dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n", + dev_dbg(dev->dev, "FW Client - Protocol Version = %d\n", me_cl->props.protocol_version); - dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n", + dev_dbg(dev->dev, "FW Client - Max Msg Len = %d\n", me_cl->props.max_msg_length); /* if we're connecting to amthif client then we will use the * existing connection */ if (uuid_le_cmp(data->in_client_uuid, mei_amthif_guid) == 0) { - dev_dbg(&dev->pdev->dev, "FW Client is amthi\n"); + dev_dbg(dev->dev, "FW Client is amthi\n"); if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { rets = -ENODEV; goto end; @@ -493,7 +493,7 @@ static int mei_ioctl_connect_client(struct file *file, client = &data->out_client_properties; client->max_msg_length = me_cl->props.max_msg_length; client->protocol_version = me_cl->props.protocol_version; - dev_dbg(&dev->pdev->dev, "Can connect?\n"); + dev_dbg(dev->dev, "Can connect?\n"); rets = mei_cl_connect(cl, file); @@ -524,7 +524,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) dev = cl->dev; - dev_dbg(&dev->pdev->dev, "IOCTL cmd = 0x%x", cmd); + dev_dbg(dev->dev, "IOCTL cmd = 0x%x", cmd); mutex_lock(&dev->device_lock); if (dev->dev_state != MEI_DEV_ENABLED) { @@ -534,10 +534,10 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) switch (cmd) { case IOCTL_MEI_CONNECT_CLIENT: - dev_dbg(&dev->pdev->dev, ": IOCTL_MEI_CONNECT_CLIENT.\n"); + dev_dbg(dev->dev, ": IOCTL_MEI_CONNECT_CLIENT.\n"); if (copy_from_user(&connect_data, (char __user *)data, sizeof(struct mei_connect_client_data))) { - dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n"); + dev_dbg(dev->dev, "failed to copy data from userland\n"); rets = -EFAULT; goto out; } @@ -549,7 +549,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) /* if all is ok, copying the data back to user. */ if (copy_to_user((char __user *)data, &connect_data, sizeof(struct mei_connect_client_data))) { - dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n"); + dev_dbg(dev->dev, "failed to copy data to userland\n"); rets = -EFAULT; goto out; } @@ -557,7 +557,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) break; default: - dev_err(&dev->pdev->dev, ": unsupported ioctl %d.\n", cmd); + dev_err(dev->dev, ": unsupported ioctl %d.\n", cmd); rets = -ENOIOCTLCMD; } @@ -671,7 +671,7 @@ static int mei_minor_get(struct mei_device *dev) if (ret >= 0) dev->minor = ret; else if (ret == -ENOSPC) - dev_err(&dev->pdev->dev, "too many mei devices\n"); + dev_err(dev->dev, "too many mei devices\n"); mutex_unlock(&mei_minor_lock); return ret; diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c index 8cc93e4756b3..9f32fd6eaccf 100644 --- a/drivers/misc/mei/nfc.c +++ b/drivers/misc/mei/nfc.c @@ -163,7 +163,7 @@ static int mei_nfc_build_bus_name(struct mei_nfc_dev *ndev) return 0; default: - dev_err(&dev->pdev->dev, "Unknown radio type 0x%x\n", + dev_err(dev->dev, "Unknown radio type 0x%x\n", ndev->radio_type); return -EINVAL; @@ -175,14 +175,14 @@ static int mei_nfc_build_bus_name(struct mei_nfc_dev *ndev) ndev->bus_name = "pn544"; return 0; default: - dev_err(&dev->pdev->dev, "Unknown radio type 0x%x\n", + dev_err(dev->dev, "Unknown radio type 0x%x\n", ndev->radio_type); return -EINVAL; } default: - dev_err(&dev->pdev->dev, "Unknown vendor ID 0x%x\n", + dev_err(dev->dev, "Unknown vendor ID 0x%x\n", ndev->vendor_id); return -EINVAL; @@ -231,21 +231,21 @@ static int mei_nfc_connect(struct mei_nfc_dev *ndev) ret = __mei_cl_send(cl, (u8 *)cmd, connect_length); if (ret < 0) { - dev_err(&dev->pdev->dev, "Could not send connect cmd\n"); + dev_err(dev->dev, "Could not send connect cmd\n"); goto err; } bytes_recv = __mei_cl_recv(cl, (u8 *)reply, connect_resp_length); if (bytes_recv < 0) { - dev_err(&dev->pdev->dev, "Could not read connect response\n"); + dev_err(dev->dev, "Could not read connect response\n"); ret = bytes_recv; goto err; } - dev_info(&dev->pdev->dev, "IVN 0x%x Vendor ID 0x%x\n", + dev_info(dev->dev, "IVN 0x%x Vendor ID 0x%x\n", connect_resp->fw_ivn, connect_resp->vendor_id); - dev_info(&dev->pdev->dev, "ME FW %d.%d.%d.%d\n", + dev_info(dev->dev, "ME FW %d.%d.%d.%d\n", connect_resp->me_major, connect_resp->me_minor, connect_resp->me_hotfix, connect_resp->me_build); @@ -279,7 +279,7 @@ static int mei_nfc_if_version(struct mei_nfc_dev *ndev) ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(struct mei_nfc_cmd)); if (ret < 0) { - dev_err(&dev->pdev->dev, "Could not send IF version cmd\n"); + dev_err(dev->dev, "Could not send IF version cmd\n"); return ret; } @@ -293,7 +293,7 @@ static int mei_nfc_if_version(struct mei_nfc_dev *ndev) bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length); if (bytes_recv < 0 || bytes_recv < sizeof(struct mei_nfc_reply)) { - dev_err(&dev->pdev->dev, "Could not read IF version\n"); + dev_err(dev->dev, "Could not read IF version\n"); ret = -EIO; goto err; } @@ -319,7 +319,7 @@ static int mei_nfc_enable(struct mei_cl_device *cldev) ret = mei_nfc_connect(ndev); if (ret < 0) { - dev_err(&dev->pdev->dev, "Could not connect to NFC"); + dev_err(dev->dev, "Could not connect to NFC"); return ret; } @@ -361,7 +361,7 @@ static int mei_nfc_send(struct mei_cl_device *cldev, u8 *buf, size_t length) if (!wait_event_interruptible_timeout(ndev->send_wq, ndev->recv_req_id == ndev->req_id, HZ)) { - dev_err(&dev->pdev->dev, "NFC MEI command timeout\n"); + dev_err(dev->dev, "NFC MEI command timeout\n"); err = -ETIME; } else { ndev->req_id++; @@ -418,8 +418,7 @@ static void mei_nfc_init(struct work_struct *work) if (mei_cl_connect(cl_info, NULL) < 0) { mutex_unlock(&dev->device_lock); - dev_err(&dev->pdev->dev, - "Could not connect to the NFC INFO ME client"); + dev_err(dev->dev, "Could not connect to the NFC INFO ME client"); goto err; } @@ -427,21 +426,19 @@ static void mei_nfc_init(struct work_struct *work) mutex_unlock(&dev->device_lock); if (mei_nfc_if_version(ndev) < 0) { - dev_err(&dev->pdev->dev, "Could not get the NFC interface version"); + dev_err(dev->dev, "Could not get the NFC interface version"); goto err; } - dev_info(&dev->pdev->dev, - "NFC MEI VERSION: IVN 0x%x Vendor ID 0x%x Type 0x%x\n", + dev_info(dev->dev, "NFC MEI VERSION: IVN 0x%x Vendor ID 0x%x Type 0x%x\n", ndev->fw_ivn, ndev->vendor_id, ndev->radio_type); mutex_lock(&dev->device_lock); if (mei_cl_disconnect(cl_info) < 0) { mutex_unlock(&dev->device_lock); - dev_err(&dev->pdev->dev, - "Could not disconnect the NFC INFO ME client"); + dev_err(dev->dev, "Could not disconnect the NFC INFO ME client"); goto err; } @@ -449,15 +446,13 @@ static void mei_nfc_init(struct work_struct *work) mutex_unlock(&dev->device_lock); if (mei_nfc_build_bus_name(ndev) < 0) { - dev_err(&dev->pdev->dev, - "Could not build the bus ID name\n"); + dev_err(dev->dev, "Could not build the bus ID name\n"); return; } cldev = mei_cl_add_device(dev, mei_nfc_guid, ndev->bus_name, &nfc_ops); if (!cldev) { - dev_err(&dev->pdev->dev, - "Could not add the NFC device to the MEI bus\n"); + dev_err(dev->dev, "Could not add the NFC device to the MEI bus\n"); goto err; } @@ -500,7 +495,7 @@ int mei_nfc_host_init(struct mei_device *dev) /* check for valid client id */ me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_info_guid); if (!me_cl) { - dev_info(&dev->pdev->dev, "nfc: failed to find the client\n"); + dev_info(dev->dev, "nfc: failed to find the client\n"); ret = -ENOTTY; goto err; } @@ -518,7 +513,7 @@ int mei_nfc_host_init(struct mei_device *dev) /* check for valid client id */ me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_guid); if (!me_cl) { - dev_info(&dev->pdev->dev, "nfc: failed to find the client\n"); + dev_info(dev->dev, "nfc: failed to find the client\n"); ret = -ENOTTY; goto err; } diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index a0e9422b55a2..83e88920f738 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -451,7 +451,7 @@ static inline void mei_me_set_pm_domain(struct mei_device *dev) static inline void mei_me_unset_pm_domain(struct mei_device *dev) { /* stop using pm callbacks if any */ - dev->pdev->dev.pm_domain = NULL; + dev->dev->pm_domain = NULL; } #endif /* CONFIG_PM_RUNTIME */ diff --git a/drivers/misc/mei/pci-txe.c b/drivers/misc/mei/pci-txe.c index a5ce2ab98af2..a1f60be873f5 100644 --- a/drivers/misc/mei/pci-txe.c +++ b/drivers/misc/mei/pci-txe.c @@ -399,7 +399,7 @@ static inline void mei_txe_set_pm_domain(struct mei_device *dev) static inline void mei_txe_unset_pm_domain(struct mei_device *dev) { /* stop using pm callbacks if any */ - dev->pdev->dev.pm_domain = NULL; + dev->dev->pm_domain = NULL; } #endif /* CONFIG_PM_RUNTIME */ diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 40f46e4c2e9c..d28511b78eaa 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -42,7 +42,7 @@ 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); + dev_dbg(dev->dev, "wd: set timeout=%d.\n", timeout); memcpy(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE); memcpy(dev->wd_data + MEI_WD_HDR_SIZE, &timeout, sizeof(u16)); } @@ -71,7 +71,7 @@ int mei_wd_host_init(struct mei_device *dev) /* check for valid client id */ me_cl = mei_me_cl_by_uuid(dev, &mei_wd_guid); if (!me_cl) { - dev_info(&dev->pdev->dev, "wd: failed to find the client\n"); + dev_info(dev->dev, "wd: failed to find the client\n"); return -ENOTTY; } @@ -81,14 +81,14 @@ int mei_wd_host_init(struct mei_device *dev) ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID); if (ret < 0) { - dev_info(&dev->pdev->dev, "wd: failed link client\n"); + dev_info(dev->dev, "wd: failed link client\n"); return ret; } ret = mei_cl_connect(cl, NULL); if (ret) { - dev_err(&dev->pdev->dev, "wd: failed to connect = %d\n", ret); + dev_err(dev->dev, "wd: failed to connect = %d\n", ret); mei_cl_unlink(cl); return ret; } @@ -128,19 +128,19 @@ int mei_wd_send(struct mei_device *dev) else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_HDR_SIZE)) hdr.length = MEI_WD_STOP_MSG_SIZE; else { - dev_err(&dev->pdev->dev, "wd: invalid message is to be sent, aborting\n"); + dev_err(dev->dev, "wd: invalid message is to be sent, aborting\n"); return -EINVAL; } ret = mei_write_message(dev, &hdr, dev->wd_data); if (ret) { - dev_err(&dev->pdev->dev, "wd: write message failed\n"); + dev_err(dev->dev, "wd: write message failed\n"); return ret; } ret = mei_cl_flow_ctrl_reduce(cl); if (ret) { - dev_err(&dev->pdev->dev, "wd: flow_ctrl_reduce failed.\n"); + dev_err(dev->dev, "wd: flow_ctrl_reduce failed.\n"); return ret; } @@ -193,11 +193,10 @@ int mei_wd_stop(struct mei_device *dev) if (dev->wd_state != MEI_WD_IDLE) { /* timeout */ ret = -ETIME; - dev_warn(&dev->pdev->dev, - "wd: stop failed to complete ret=%d.\n", ret); + dev_warn(dev->dev, "wd: stop failed to complete ret=%d\n", ret); goto err; } - dev_dbg(&dev->pdev->dev, "wd: stop completed after %u msec\n", + dev_dbg(dev->dev, "wd: stop completed after %u msec\n", MEI_WD_STOP_TIMEOUT - jiffies_to_msecs(ret)); return 0; err: @@ -223,15 +222,13 @@ static int mei_wd_ops_start(struct watchdog_device *wd_dev) mutex_lock(&dev->device_lock); if (dev->dev_state != MEI_DEV_ENABLED) { - dev_dbg(&dev->pdev->dev, - "wd: dev_state != MEI_DEV_ENABLED dev_state = %s\n", + dev_dbg(dev->dev, "wd: dev_state != MEI_DEV_ENABLED dev_state = %s\n", mei_dev_state_str(dev->dev_state)); goto end_unlock; } if (dev->wd_cl.state != MEI_FILE_CONNECTED) { - dev_dbg(&dev->pdev->dev, - "MEI Driver is not connected to Watchdog Client\n"); + dev_dbg(dev->dev, "MEI Driver is not connected to Watchdog Client\n"); goto end_unlock; } @@ -284,7 +281,7 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev) mutex_lock(&dev->device_lock); if (dev->wd_cl.state != MEI_FILE_CONNECTED) { - dev_err(&dev->pdev->dev, "wd: not connected.\n"); + dev_err(dev->dev, "wd: not connected.\n"); ret = -ENODEV; goto end; } @@ -297,7 +294,7 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev) /* Check if we can send the ping to HW*/ if (ret && mei_hbuf_acquire(dev)) { - dev_dbg(&dev->pdev->dev, "wd: sending ping\n"); + dev_dbg(dev->dev, "wd: sending ping\n"); ret = mei_wd_send(dev); if (ret) @@ -380,13 +377,12 @@ int mei_watchdog_register(struct mei_device *dev) ret = watchdog_register_device(&amt_wd_dev); mutex_lock(&dev->device_lock); if (ret) { - dev_err(&dev->pdev->dev, "wd: unable to register watchdog device = %d.\n", + dev_err(dev->dev, "wd: unable to register watchdog device = %d.\n", ret); return ret; } - dev_dbg(&dev->pdev->dev, - "wd: successfully register watchdog interface.\n"); + dev_dbg(dev->dev, "wd: successfully register watchdog interface.\n"); watchdog_set_drvdata(&amt_wd_dev, dev); return 0; } -- cgit v1.2.3 From 1bd30b6a42610466bae2c133e68a8feb1004929c Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 29 Sep 2014 16:31:43 +0300 Subject: mei: move fw_status back to hw ops handlers fw status retrieval has pci specific implementation so we push it back to the hw layer Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me.c | 28 ++++++++++++++++++++++++++++ drivers/misc/mei/hw-txe.c | 30 ++++++++++++++++++++++++++++++ drivers/misc/mei/init.c | 21 --------------------- drivers/misc/mei/mei_dev.h | 9 ++++++++- 4 files changed, 66 insertions(+), 22 deletions(-) diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 1247be706216..678531c08c6d 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -101,6 +101,33 @@ static inline void mei_hcsr_set(struct mei_me_hw *hw, u32 hcsr) mei_me_reg_write(hw, H_CSR, hcsr); } +/** + * mei_me_fw_status - read fw status register from pci config space + * + * @dev: mei device + * @fw_status: fw status register values + */ +static int mei_me_fw_status(struct mei_device *dev, + struct mei_fw_status *fw_status) +{ + const struct mei_fw_status *fw_src = &dev->cfg->fw_status; + struct pci_dev *pdev = to_pci_dev(dev->dev); + int ret; + int i; + + if (!fw_status) + return -EINVAL; + + fw_status->count = fw_src->count; + for (i = 0; i < fw_src->count && i < MEI_FW_STATUS_MAX; i++) { + ret = pci_read_config_dword(pdev, + fw_src->status[i], &fw_status->status[i]); + if (ret) + return ret; + } + + return 0; +} /** * mei_me_hw_config - configure hw dependent settings @@ -714,6 +741,7 @@ end: static const struct mei_hw_ops mei_me_hw_ops = { + .fw_status = mei_me_fw_status, .pg_state = mei_me_pg_state, .host_is_ready = mei_me_host_is_ready, diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index acc475eec150..e4cb9dc2d198 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c @@ -573,6 +573,35 @@ static int mei_txe_readiness_wait(struct mei_device *dev) return 0; } + +/** + * mei_txe_fw_status - read fw status register from pci config space + * + * @dev: mei device + * @fw_status: fw status register values + */ +static int mei_txe_fw_status(struct mei_device *dev, + struct mei_fw_status *fw_status) +{ + const struct mei_fw_status *fw_src = &dev->cfg->fw_status; + struct pci_dev *pdev = to_pci_dev(dev->dev); + int ret; + int i; + + if (!fw_status) + return -EINVAL; + + fw_status->count = fw_src->count; + for (i = 0; i < fw_src->count && i < MEI_FW_STATUS_MAX; i++) { + ret = pci_read_config_dword(pdev, + fw_src->status[i], &fw_status->status[i]); + if (ret) + return ret; + } + + return 0; +} + /** * mei_txe_hw_config - configure hardware at the start of the devices * @@ -1064,6 +1093,7 @@ static const struct mei_hw_ops mei_txe_hw_ops = { .host_is_ready = mei_txe_host_is_ready, + .fw_status = mei_txe_fw_status, .pg_state = mei_txe_pg_state, .hw_is_ready = mei_txe_hw_is_ready, diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 29aae7b7a304..dd233fd43178 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -344,27 +344,6 @@ bool mei_write_is_idle(struct mei_device *dev) } EXPORT_SYMBOL_GPL(mei_write_is_idle); -int mei_fw_status(struct mei_device *dev, struct mei_fw_status *fw_status) -{ - const struct mei_fw_status *fw_src = &dev->cfg->fw_status; - int ret; - int i; - - if (!fw_status) - return -EINVAL; - - fw_status->count = fw_src->count; - for (i = 0; i < fw_src->count && i < MEI_FW_STATUS_MAX; i++) { - ret = pci_read_config_dword(dev->pdev, - fw_src->status[i], &fw_status->status[i]); - if (ret) - return ret; - } - - return 0; -} -EXPORT_SYMBOL_GPL(mei_fw_status); - /** * mei_device_init -- initialize mei_device structure * diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 705143023255..7080fff11595 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -233,6 +233,7 @@ struct mei_cl { * @hw_start - start hw after reset * @hw_config - configure hw + * @fw_status - get fw status registers * @pg_state - power gating state of the device * @pg_is_enabled - is power gating enabled @@ -260,6 +261,8 @@ struct mei_hw_ops { int (*hw_start)(struct mei_device *dev); void (*hw_config)(struct mei_device *dev); + + int (*fw_status)(struct mei_device *dev, struct mei_fw_status *fw_sts); enum mei_pg_state (*pg_state)(struct mei_device *dev); bool (*pg_is_enabled)(struct mei_device *dev); @@ -731,7 +734,11 @@ static inline int mei_count_full_read_slots(struct mei_device *dev) return dev->ops->rdbuf_full_slots(dev); } -int mei_fw_status(struct mei_device *dev, struct mei_fw_status *fw_status); +static inline int mei_fw_status(struct mei_device *dev, + struct mei_fw_status *fw_status) +{ + return dev->ops->fw_status(dev, fw_status); +} #define FW_STS_FMT "%08X %08X" #define FW_STS_PRM(fw_status) \ -- cgit v1.2.3 From d08b8fc0dbdbe9bf7edeb46f7a856f993630664f Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 29 Sep 2014 16:31:44 +0300 Subject: mei: remove the reference to pdev from mei_device For purpose of adding testing HW we would like to get rid of pci dependency in generic mei code. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me.c | 3 +-- drivers/misc/mei/hw-txe.c | 3 +-- drivers/misc/mei/mei_dev.h | 2 -- drivers/misc/mei/pci-me.c | 2 +- drivers/misc/mei/pci-txe.c | 2 +- 5 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 678531c08c6d..da86310d7899 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -676,7 +676,7 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) /* Ack the interrupt here * In case of MSI we don't go through the quick handler */ - if (pci_dev_msi_enabled(dev->pdev)) + if (pci_dev_msi_enabled(to_pci_dev(dev->dev))) mei_clear_interrupts(dev); /* check if ME wants a reset */ @@ -854,7 +854,6 @@ struct mei_device *mei_me_dev_init(struct pci_dev *pdev, mei_device_init(dev, &pdev->dev, &mei_me_hw_ops); dev->cfg = cfg; - dev->pdev = pdev; return dev; } diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index e4cb9dc2d198..6eef6766f0a5 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c @@ -998,7 +998,7 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id) mutex_lock(&dev->device_lock); mei_io_list_init(&complete_list); - if (pci_dev_msi_enabled(dev->pdev)) + if (pci_dev_msi_enabled(to_pci_dev(dev->dev))) mei_txe_check_and_ack_intrs(dev, true); /* show irq events */ @@ -1157,7 +1157,6 @@ struct mei_device *mei_txe_dev_init(struct pci_dev *pdev, init_waitqueue_head(&hw->wait_aliveness_resp); dev->cfg = cfg; - dev->pdev = pdev; return dev; } diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 7080fff11595..5a16cc46f8d6 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -401,7 +401,6 @@ struct mei_cfg { /** * struct mei_device - MEI private device struct - * @pdev - pointer to pci device struct * @dev - device on a bus * @cdev - character device * @minor - minor number allocated for device @@ -420,7 +419,6 @@ struct mei_cfg { * @cfg - per device generation config and ops */ struct mei_device { - struct pci_dev *pdev; /* pointer to pci device struct */ struct device *dev; struct cdev cdev; int minor; diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 83e88920f738..a91071716868 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -430,7 +430,7 @@ static int mei_me_pm_runtime_resume(struct device *device) */ static inline void mei_me_set_pm_domain(struct mei_device *dev) { - struct pci_dev *pdev = dev->pdev; + struct pci_dev *pdev = to_pci_dev(dev->dev); if (pdev->dev.bus && pdev->dev.bus->pm) { dev->pg_domain.ops = *pdev->dev.bus->pm; diff --git a/drivers/misc/mei/pci-txe.c b/drivers/misc/mei/pci-txe.c index a1f60be873f5..cd9dda705006 100644 --- a/drivers/misc/mei/pci-txe.c +++ b/drivers/misc/mei/pci-txe.c @@ -378,7 +378,7 @@ static int mei_txe_pm_runtime_resume(struct device *device) */ static inline void mei_txe_set_pm_domain(struct mei_device *dev) { - struct pci_dev *pdev = dev->pdev; + struct pci_dev *pdev = to_pci_dev(dev->dev); if (pdev->dev.bus && pdev->dev.bus->pm) { dev->pg_domain.ops = *pdev->dev.bus->pm; -- cgit v1.2.3 From 4ad96db6ccdd8b777cff5fd4aa74ec1e86f1afce Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 29 Sep 2014 16:31:45 +0300 Subject: mei: push pci cfg structure me hw Device specific configurations are currently only needed by me hw so we can remove it from txe Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me.c | 7 +++++-- drivers/misc/mei/hw-me.h | 26 +++++++++++++++++++++++++- drivers/misc/mei/hw-txe.c | 22 +++++++--------------- drivers/misc/mei/hw-txe.h | 5 +---- drivers/misc/mei/mei_dev.h | 20 -------------------- drivers/misc/mei/pci-txe.c | 6 +++--- 6 files changed, 41 insertions(+), 45 deletions(-) diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index da86310d7899..77166ea30a4d 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -110,8 +110,9 @@ static inline void mei_hcsr_set(struct mei_me_hw *hw, u32 hcsr) static int mei_me_fw_status(struct mei_device *dev, struct mei_fw_status *fw_status) { - const struct mei_fw_status *fw_src = &dev->cfg->fw_status; struct pci_dev *pdev = to_pci_dev(dev->dev); + struct mei_me_hw *hw = to_me_hw(dev); + const struct mei_fw_status *fw_src = &hw->cfg->fw_status; int ret; int i; @@ -846,14 +847,16 @@ struct mei_device *mei_me_dev_init(struct pci_dev *pdev, const struct mei_cfg *cfg) { struct mei_device *dev; + struct mei_me_hw *hw; dev = kzalloc(sizeof(struct mei_device) + sizeof(struct mei_me_hw), GFP_KERNEL); if (!dev) return NULL; + hw = to_me_hw(dev); mei_device_init(dev, &pdev->dev, &mei_me_hw_ops); - dev->cfg = cfg; + hw->cfg = cfg; return dev; } diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h index 12b0f4bbe1f1..b0001b3a0fb5 100644 --- a/drivers/misc/mei/hw-me.h +++ b/drivers/misc/mei/hw-me.h @@ -19,14 +19,38 @@ #ifndef _MEI_INTERFACE_H_ #define _MEI_INTERFACE_H_ -#include #include +#include +#include + #include "mei_dev.h" #include "client.h" +/* + * mei_cfg - mei device configuration + * + * @fw_status: FW status + * @quirk_probe: device exclusion quirk + */ +struct mei_cfg { + const struct mei_fw_status fw_status; + bool (*quirk_probe)(struct pci_dev *pdev); +}; + + +#define MEI_PCI_DEVICE(dev, cfg) \ + .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ + .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, \ + .driver_data = (kernel_ulong_t)&(cfg) + + #define MEI_ME_RPM_TIMEOUT 500 /* ms */ +/** + * @cfg: per device generation config and ops + */ struct mei_me_hw { + const struct mei_cfg *cfg; void __iomem *mem_addr; /* * hw states of host and fw(ME) diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index 6eef6766f0a5..f33fbcbcdf63 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c @@ -573,6 +573,11 @@ static int mei_txe_readiness_wait(struct mei_device *dev) return 0; } +const struct mei_fw_status mei_txe_fw_sts = { + .count = 2, + .status[0] = PCI_CFG_TXE_FW_STS0, + .status[1] = PCI_CFG_TXE_FW_STS1 +}; /** * mei_txe_fw_status - read fw status register from pci config space @@ -583,7 +588,7 @@ static int mei_txe_readiness_wait(struct mei_device *dev) static int mei_txe_fw_status(struct mei_device *dev, struct mei_fw_status *fw_status) { - const struct mei_fw_status *fw_src = &dev->cfg->fw_status; + const struct mei_fw_status *fw_src = &mei_txe_fw_sts; struct pci_dev *pdev = to_pci_dev(dev->dev); int ret; int i; @@ -1120,27 +1125,15 @@ static const struct mei_hw_ops mei_txe_hw_ops = { }; -#define MEI_CFG_TXE_FW_STS \ - .fw_status.count = 2, \ - .fw_status.status[0] = PCI_CFG_TXE_FW_STS0, \ - .fw_status.status[1] = PCI_CFG_TXE_FW_STS1 - -const struct mei_cfg mei_txe_cfg = { - MEI_CFG_TXE_FW_STS, -}; - - /** * mei_txe_dev_init - allocates and initializes txe hardware specific structure * * @pdev - pci device - * @cfg - per device generation config * * returns struct mei_device * on success or NULL; * */ -struct mei_device *mei_txe_dev_init(struct pci_dev *pdev, - const struct mei_cfg *cfg) +struct mei_device *mei_txe_dev_init(struct pci_dev *pdev) { struct mei_device *dev; struct mei_txe_hw *hw; @@ -1156,7 +1149,6 @@ struct mei_device *mei_txe_dev_init(struct pci_dev *pdev, init_waitqueue_head(&hw->wait_aliveness_resp); - dev->cfg = cfg; return dev; } diff --git a/drivers/misc/mei/hw-txe.h b/drivers/misc/mei/hw-txe.h index e244af79167f..e8dd2d165c25 100644 --- a/drivers/misc/mei/hw-txe.h +++ b/drivers/misc/mei/hw-txe.h @@ -61,10 +61,7 @@ static inline struct mei_device *hw_txe_to_mei(struct mei_txe_hw *hw) return container_of((void *)hw, struct mei_device, hw); } -extern const struct mei_cfg mei_txe_cfg; - -struct mei_device *mei_txe_dev_init(struct pci_dev *pdev, - const struct mei_cfg *cfg); +struct mei_device *mei_txe_dev_init(struct pci_dev *pdev); irqreturn_t mei_txe_irq_quick_handler(int irq, void *dev_id); irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 5a16cc46f8d6..fed4c96da0fa 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -380,24 +380,6 @@ enum mei_pg_state { const char *mei_pg_state_str(enum mei_pg_state state); -/* - * mei_cfg - * - * @fw_status - FW status - * @quirk_probe - device exclusion quirk - */ -struct mei_cfg { - const struct mei_fw_status fw_status; - bool (*quirk_probe)(struct pci_dev *pdev); -}; - - -#define MEI_PCI_DEVICE(dev, cfg) \ - .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ - .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, \ - .driver_data = (kernel_ulong_t)&(cfg) - - /** * struct mei_device - MEI private device struct @@ -416,7 +398,6 @@ struct mei_cfg { * @hbuf_depth - depth of hardware host/write buffer is slots * @hbuf_is_ready - query if the host host/write buffer is ready * @wr_msg - the buffer for hbm control messages - * @cfg - per device generation config and ops */ struct mei_device { struct device *dev; @@ -530,7 +511,6 @@ struct mei_device { const struct mei_hw_ops *ops; - const struct mei_cfg *cfg; char hw[0] __aligned(sizeof(void *)); }; diff --git a/drivers/misc/mei/pci-txe.c b/drivers/misc/mei/pci-txe.c index cd9dda705006..69eb999ae803 100644 --- a/drivers/misc/mei/pci-txe.c +++ b/drivers/misc/mei/pci-txe.c @@ -36,7 +36,8 @@ #include "hw-txe.h" static const struct pci_device_id mei_txe_pci_tbl[] = { - {MEI_PCI_DEVICE(0x0F18, mei_txe_cfg)}, /* Baytrail */ + {PCI_VDEVICE(INTEL, 0x0F18)}, /* Baytrail */ + {0, } }; MODULE_DEVICE_TABLE(pci, mei_txe_pci_tbl); @@ -70,7 +71,6 @@ static void mei_txe_pci_iounmap(struct pci_dev *pdev, struct mei_txe_hw *hw) */ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - const struct mei_cfg *cfg = (struct mei_cfg *)(ent->driver_data); struct mei_device *dev; struct mei_txe_hw *hw; int err; @@ -101,7 +101,7 @@ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } /* allocates and initializes the mei dev structure */ - dev = mei_txe_dev_init(pdev, cfg); + dev = mei_txe_dev_init(pdev); if (!dev) { err = -ENOMEM; goto release_regions; -- cgit v1.2.3 From 1f180359f42fc6fda4600175c63f2a84f444cc92 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 29 Sep 2014 16:31:46 +0300 Subject: mei: remove include to pci header from mei module files Remove inclusion of linux/pci.h in mei layer however we need to include the headers that before got included implicitly from linux/pci.h. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 2 +- drivers/misc/mei/bus.c | 1 - drivers/misc/mei/client.c | 2 +- drivers/misc/mei/debugfs.c | 1 - drivers/misc/mei/hbm.c | 5 +++-- drivers/misc/mei/init.c | 1 - drivers/misc/mei/interrupt.c | 2 +- drivers/misc/mei/main.c | 2 +- drivers/misc/mei/nfc.c | 3 ++- drivers/misc/mei/wd.c | 1 - include/linux/mei_cl_bus.h | 1 + 11 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 5d47d1b36ccf..d9b0e761fcd2 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include #include diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 4cc1a66187be..4d20d60ca38d 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include "mei_dev.h" diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index bfc3ad24db9c..04a196429e55 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -14,10 +14,10 @@ * */ -#include #include #include #include +#include #include #include diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index e14a7db9a669..aca7847da69f 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c @@ -17,7 +17,6 @@ #include #include #include -#include #include diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 209650bccf57..c874fdd44ce1 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -15,11 +15,12 @@ */ #include -#include #include #include -#include #include +#include + +#include #include "mei_dev.h" #include "hbm.h" diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index dd233fd43178..76ef8ffa42c1 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -15,7 +15,6 @@ */ #include -#include #include #include #include diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 8dac76901130..8844e1772793 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -16,11 +16,11 @@ #include -#include #include #include #include #include +#include #include diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 4d738c881878..d31f271f6516 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -17,12 +17,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c index 9f32fd6eaccf..5b369f4c47de 100644 --- a/drivers/misc/mei/nfc.c +++ b/drivers/misc/mei/nfc.c @@ -19,7 +19,8 @@ #include #include #include -#include +#include + #include #include "mei_dev.h" diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index d28511b78eaa..626b4c13993b 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include diff --git a/include/linux/mei_cl_bus.h b/include/linux/mei_cl_bus.h index d14af7b722ef..164aad1f9f12 100644 --- a/include/linux/mei_cl_bus.h +++ b/include/linux/mei_cl_bus.h @@ -3,6 +3,7 @@ #include #include +#include struct mei_cl_device; -- cgit v1.2.3 From 0a01e97432a6ee5c5b78c0425dd7518a80f87b54 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Mon, 29 Sep 2014 16:31:47 +0300 Subject: mei: trivial: fix errors in prints in comments Fix misspellings and wrong print texts Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 2 +- drivers/misc/mei/debugfs.c | 2 +- drivers/misc/mei/hw-txe.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 04a196429e55..bf3fd67dc6b6 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -926,7 +926,7 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking) buf = &cb->request_buffer; - cl_dbg(dev, cl, "mei_cl_write %d\n", buf->size); + cl_dbg(dev, cl, "size=%d\n", buf->size); rets = pm_runtime_get(dev->dev); if (rets < 0 && rets != -EINPROGRESS) { diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index aca7847da69f..b92b8bc136ac 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c @@ -105,7 +105,7 @@ static ssize_t mei_dbgfs_read_active(struct file *fp, char __user *ubuf, mutex_lock(&dev->device_lock); - /* if the driver is not enabled the list won't b consitent */ + /* if the driver is not enabled the list won't be consistent */ if (dev->dev_state != MEI_DEV_ENABLED) goto out; diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index f33fbcbcdf63..695d480e44dc 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c @@ -841,7 +841,7 @@ static int mei_txe_hw_reset(struct mei_device *dev, bool intr_enable) } /* - * Set rediness RDY_CLR bit + * Set readiness RDY_CLR bit */ mei_txe_readiness_clear(dev); @@ -867,7 +867,7 @@ static int mei_txe_hw_start(struct mei_device *dev) ret = mei_txe_readiness_wait(dev); if (ret < 0) { - dev_err(dev->dev, "wating for readiness failed\n"); + dev_err(dev->dev, "waiting for readiness failed\n"); return ret; } -- cgit v1.2.3 From 764c065a65c31a09340e71d2c41652e7e05bf083 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Mon, 29 Sep 2014 16:31:48 +0300 Subject: mei: drop me_client_presentation_num me_client_presentation_num field is not used for any particular purpose now, so it can be safely dropped. Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hbm.c | 2 -- drivers/misc/mei/mei_dev.h | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index c874fdd44ce1..92d0739cca85 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -126,7 +126,6 @@ static void mei_me_cl_remove_all(struct mei_device *dev) */ void mei_hbm_reset(struct mei_device *dev) { - dev->me_client_presentation_num = 0; dev->me_client_index = 0; mei_me_cl_remove_all(dev); @@ -883,7 +882,6 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) mei_hbm_me_cl_add(dev, props_res); dev->me_client_index++; - dev->me_client_presentation_num++; /* request property for the next client */ if (mei_hbm_prop_req(dev)) diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index fed4c96da0fa..0a1f2b735706 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -470,7 +470,6 @@ struct mei_device { struct list_head me_clients; DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX); - unsigned long me_client_presentation_num; unsigned long me_client_index; struct mei_cl wd_cl; -- cgit v1.2.3 From a8605ea2c20c2b97a54d7746c16ebef5ba29632a Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Mon, 29 Sep 2014 16:31:49 +0300 Subject: mei: fix KDoc documentation formatting Fix Kdoc documentation formatting warnings genertaed by ./scripts/kernel-doc Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 30 +++++++-------- drivers/misc/mei/client.c | 70 ++++++++++++++++++++--------------- drivers/misc/mei/debugfs.c | 7 +++- drivers/misc/mei/hbm.c | 43 +++++++++++----------- drivers/misc/mei/hw-me.c | 48 ++++++++++++------------ drivers/misc/mei/hw-txe.c | 57 +++++++++++++++------------- drivers/misc/mei/hw.h | 46 +++++++++++------------ drivers/misc/mei/init.c | 10 ++--- drivers/misc/mei/interrupt.c | 24 ++++++------ drivers/misc/mei/main.c | 21 +++++------ drivers/misc/mei/mei_dev.h | 88 ++++++++++++++++++++++---------------------- drivers/misc/mei/nfc.c | 3 +- drivers/misc/mei/pci-me.c | 4 +- drivers/misc/mei/pci-txe.c | 2 +- drivers/misc/mei/wd.c | 15 ++++---- 15 files changed, 243 insertions(+), 225 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index d9b0e761fcd2..29b3fd0ab505 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -122,7 +122,7 @@ int mei_amthif_host_init(struct mei_device *dev) * @dev: the device structure * @file: pointer to file object * - * returns returned a list entry on success, NULL on failure. + * Return: returned a list entry on success, NULL on failure. */ struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev, struct file *file) @@ -140,15 +140,14 @@ struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev, * mei_amthif_read - read data from AMTHIF client * * @dev: the device structure - * @if_num: minor number * @file: pointer to file object - * @*ubuf: pointer to user data in user space + * @ubuf: pointer to user data in user space * @length: data length to read * @offset: data read offset * * Locking: called under "dev->device_lock" lock * - * returns + * Return: * returned data length on success, * zero if no data to read, * negative on failure. @@ -256,7 +255,7 @@ out: * @dev: the device structure * @cb: mei call back struct * - * returns 0 on success, <0 on failure. + * Return: 0 on success, <0 on failure. * */ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) @@ -326,7 +325,7 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) * @dev: the device structure * @cb: mei call back struct * - * returns 0 on success, <0 on failure. + * Return: 0 on success, <0 on failure. * */ int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb) @@ -356,8 +355,6 @@ int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb) * mei_amthif_run_next_cmd * * @dev: the device structure - * - * returns 0 on success, <0 on failure. */ void mei_amthif_run_next_cmd(struct mei_device *dev) { @@ -420,12 +417,11 @@ unsigned int mei_amthif_poll(struct mei_device *dev, /** * mei_amthif_irq_write - write iamthif command in irq thread context. * - * @dev: the device structure. - * @cb_pos: callback block. * @cl: private data of the file object. + * @cb: callback block. * @cmpl_list: complete list. * - * returns 0, OK; otherwise, error. + * Return: 0, OK; otherwise, error. */ int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) @@ -507,7 +503,7 @@ int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, * @mei_hdr: header of amthif message * @complete_list: An instance of our list structure * - * returns 0 on success, <0 on failure. + * Return: 0 on success, <0 on failure. */ int mei_amthif_irq_read_msg(struct mei_device *dev, struct mei_msg_hdr *mei_hdr, @@ -560,7 +556,7 @@ int mei_amthif_irq_read_msg(struct mei_device *dev, * @dev: the device structure. * @slots: free slots. * - * returns 0, OK; otherwise, error. + * Return: 0, OK; otherwise, error. */ int mei_amthif_irq_read(struct mei_device *dev, s32 *slots) { @@ -590,7 +586,7 @@ int mei_amthif_irq_read(struct mei_device *dev, s32 *slots) * mei_amthif_complete - complete amthif callback. * * @dev: the device structure. - * @cb_pos: callback block. + * @cb: callback block. */ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb) { @@ -624,7 +620,7 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb) * mei_clear_list is called to clear resources associated with file * when application calls close function or Ctrl-C was pressed * - * returns true if callback removed from the list, false otherwise + * Return: true if callback removed from the list, false otherwise */ static bool mei_clear_list(struct mei_device *dev, const struct file *file, struct list_head *mei_cb_list) @@ -664,7 +660,7 @@ static bool mei_clear_list(struct mei_device *dev, * mei_clear_lists is called to clear resources associated with file * when application calls close function or Ctrl-C was pressed * - * returns true if callback removed from the list, false otherwise + * Return: true if callback removed from the list, false otherwise */ static bool mei_clear_lists(struct mei_device *dev, struct file *file) { @@ -705,7 +701,7 @@ static bool mei_clear_lists(struct mei_device *dev, struct file *file) * @dev: device structure * @file: pointer to file structure * -* returns 0 on success, <0 on error +* Return: 0 on success, <0 on error */ int mei_amthif_release(struct mei_device *dev, struct file *file) { diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index bf3fd67dc6b6..1f91c55f7af5 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -27,13 +27,14 @@ #include "client.h" /** - * mei_me_cl_by_uuid - locate index of me client + * mei_me_cl_by_uuid - locate me client by uuid * * @dev: mei device + * @uuid: me client uuid * * Locking: called under "dev->device_lock" lock * - * returns me client or NULL if not found + * Return: me client or NULL if not found */ struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *uuid) @@ -48,16 +49,15 @@ struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev, } /** - * mei_me_cl_by_id return index to me_clients for client_id + * mei_me_cl_by_id - locate me client by client id * * @dev: the device structure * @client_id: me client id * * Locking: called under "dev->device_lock" lock * - * returns me client or NULL if not found + * Return: me client or NULL if not found */ - struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id) { @@ -69,6 +69,17 @@ struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id) return NULL; } +/** + * mei_me_cl_by_uuid_id - locate me client by client id and uuid + * + * @dev: the device structure + * @uuid: me client uuid + * @client_id: me client id + * + * Locking: called under "dev->device_lock" lock + * + * Return: me client or NULL if not found + */ struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev, const uuid_le *uuid, u8 client_id) { @@ -109,7 +120,7 @@ void mei_me_cl_remove(struct mei_device *dev, const uuid_le *uuid, u8 client_id) * @cl1: host client 1 * @cl2: host client 2 * - * returns true - if the clients has same host and me ids + * Return: true - if the clients has same host and me ids * false - otherwise */ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, @@ -184,10 +195,10 @@ void mei_io_cb_free(struct mei_cl_cb *cb) /** * mei_io_cb_init - allocate and initialize io callback * - * @cl - mei client + * @cl: mei client * @fp: pointer to file structure * - * returns mei_cl_cb pointer or NULL; + * Return: mei_cl_cb pointer or NULL; */ struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp) { @@ -211,7 +222,7 @@ struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp) * @cb: io callback structure * @length: size of the buffer * - * returns 0 on success + * Return: 0 on success * -EINVAL if cb is NULL * -ENOMEM if allocation failed */ @@ -235,7 +246,7 @@ int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length) * @cb: io callback structure * @length: size of the buffer * - * returns 0 on success + * Return: 0 on success * -EINVAL if cb is NULL * -ENOMEM if allocation failed */ @@ -305,7 +316,7 @@ void mei_cl_init(struct mei_cl *cl, struct mei_device *dev) * mei_cl_allocate - allocates cl structure and sets it up. * * @dev: mei device - * returns The allocated file or NULL on failure + * Return: The allocated file or NULL on failure */ struct mei_cl *mei_cl_allocate(struct mei_device *dev) { @@ -325,7 +336,7 @@ struct mei_cl *mei_cl_allocate(struct mei_device *dev) * * @cl: host client * - * returns cb on success, NULL on error + * Return: cb on success, NULL on error */ struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl) { @@ -343,7 +354,7 @@ struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl) * @cl - host client * @id - fixed host id or -1 for generic one * - * returns 0 on success + * Return: 0 on success * -EINVAL on incorrect values * -ENONET if client not found */ @@ -455,10 +466,10 @@ void mei_host_client_init(struct work_struct *work) } /** - * mei_hbuf_acquire: try to acquire host buffer + * mei_hbuf_acquire - try to acquire host buffer * * @dev: the device structure - * returns true if host buffer was acquired + * Return: true if host buffer was acquired */ bool mei_hbuf_acquire(struct mei_device *dev) { @@ -485,7 +496,7 @@ bool mei_hbuf_acquire(struct mei_device *dev) * * Locking: called under "dev->device_lock" lock * - * returns 0 on success, <0 on failure. + * Return: 0 on success, <0 on failure. */ int mei_cl_disconnect(struct mei_cl *cl) { @@ -566,7 +577,7 @@ free: * * @cl: private data of the file object * - * returns true if other client is connected, false - otherwise. + * Return: true if other client is connected, false - otherwise. */ bool mei_cl_is_other_connecting(struct mei_cl *cl) { @@ -593,10 +604,11 @@ bool mei_cl_is_other_connecting(struct mei_cl *cl) * mei_cl_connect - connect host client to the me one * * @cl: host client + * @file: pointer to file structure * * Locking: called under "dev->device_lock" lock * - * returns 0 on success, <0 on failure. + * Return: 0 on success, <0 on failure. */ int mei_cl_connect(struct mei_cl *cl, struct file *file) { @@ -671,7 +683,7 @@ out: * * @cl: private data of the file object * - * returns 1 if mei_flow_ctrl_creds >0, 0 - otherwise. + * Return: 1 if mei_flow_ctrl_creds >0, 0 - otherwise. * -ENOENT if mei_cl is not present * -EINVAL if single_recv_buf == 0 */ @@ -707,7 +719,7 @@ int mei_cl_flow_ctrl_creds(struct mei_cl *cl) * * @cl: private data of the file object * - * @returns + * Return: * 0 on success * -ENOENT when me client is not found * -EINVAL when ctrl credits are <= 0 @@ -745,7 +757,7 @@ int mei_cl_flow_ctrl_reduce(struct mei_cl *cl) * * @cl: host client * - * returns 0 on success, <0 on failure. + * Return: 0 on success, <0 on failure. */ int mei_cl_read_start(struct mei_cl *cl, size_t length) { @@ -823,7 +835,7 @@ out: * @cb: callback block. * @cmpl_list: complete list. * - * returns 0, OK; otherwise error. + * Return: 0, OK; otherwise error. */ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) @@ -900,12 +912,12 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, /** * mei_cl_write - submit a write cb to mei device - assumes device_lock is locked + * assumes device_lock is locked * * @cl: host client - * @cl: write callback with filled data + * @cb: write callback with filled data * - * returns number of bytes sent on success, <0 on failure. + * Return: number of bytes sent on success, <0 on failure. */ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking) { @@ -1042,7 +1054,7 @@ void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb) /** * mei_cl_all_disconnect - disconnect forcefully all connected clients * - * @dev - mei device + * @dev: mei device */ void mei_cl_all_disconnect(struct mei_device *dev) @@ -1060,7 +1072,7 @@ void mei_cl_all_disconnect(struct mei_device *dev) /** * mei_cl_all_wakeup - wake up all readers and writers they can be interrupted * - * @dev - mei device + * @dev: mei device */ void mei_cl_all_wakeup(struct mei_device *dev) { @@ -1080,8 +1092,8 @@ void mei_cl_all_wakeup(struct mei_device *dev) /** * mei_cl_all_write_clear - clear all pending writes - - * @dev - mei device + * + * @dev: mei device */ void mei_cl_all_write_clear(struct mei_device *dev) { diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index b92b8bc136ac..357b02c18d40 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c @@ -161,7 +161,8 @@ static const struct file_operations mei_dbgfs_fops_devstate = { /** * mei_dbgfs_deregister - Remove the debugfs files and directories - * @mei - pointer to mei device private data + * + * @dev: the mei device structure */ void mei_dbgfs_deregister(struct mei_device *dev) { @@ -172,8 +173,10 @@ void mei_dbgfs_deregister(struct mei_device *dev) } /** - * Add the debugfs files + * mei_dbgfs_register - Add the debugfs files * + * @dev: the mei device structure + * @name: the mei device name */ int mei_dbgfs_register(struct mei_device *dev, const char *name) { diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 92d0739cca85..da476e8cac84 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -79,7 +79,7 @@ const char *mei_hbm_state_str(enum mei_hbm_state state) * * @status: client connect response status * - * returns corresponding error code + * Return: corresponding error code */ static int mei_cl_conn_status_to_errno(enum mei_cl_connect_status status) { @@ -196,7 +196,7 @@ int mei_hbm_cl_write(struct mei_device *dev, * @cl: client * @cmd: hbm client message * - * returns true if addresses are the same + * Return: true if addresses are the same */ static inline bool mei_hbm_cl_addr_equal(struct mei_cl *cl, struct mei_hbm_cl_cmd *cmd) @@ -211,7 +211,7 @@ bool mei_hbm_cl_addr_equal(struct mei_cl *cl, struct mei_hbm_cl_cmd *cmd) * @dev: the device structure * @buf: a buffer with hbm cl command * - * returns the recipient client or NULL if not found + * Return: the recipient client or NULL if not found */ static inline struct mei_cl *mei_hbm_cl_find_by_cmd(struct mei_device *dev, void *buf) @@ -231,7 +231,7 @@ struct mei_cl *mei_hbm_cl_find_by_cmd(struct mei_device *dev, void *buf) * * @dev: the device structure * - * returns 0 on success and < 0 on failure + * Return: 0 on success and < 0 on failure */ int mei_hbm_start_wait(struct mei_device *dev) { @@ -259,7 +259,7 @@ int mei_hbm_start_wait(struct mei_device *dev) * * @dev: the device structure * - * returns 0 on success and < 0 on failure + * Return: 0 on success and < 0 on failure */ int mei_hbm_start_req(struct mei_device *dev) { @@ -297,7 +297,7 @@ int mei_hbm_start_req(struct mei_device *dev) * * @dev: the device structure * - * returns 0 on success and < 0 on failure + * Return: 0 on success and < 0 on failure */ static int mei_hbm_enum_clients_req(struct mei_device *dev) { @@ -330,7 +330,7 @@ static int mei_hbm_enum_clients_req(struct mei_device *dev) * @dev: the device structure * @res: hbm property response * - * returns 0 on success and -ENOMEM on allocation failure + * Return: 0 on success and -ENOMEM on allocation failure */ static int mei_hbm_me_cl_add(struct mei_device *dev, @@ -355,7 +355,7 @@ static int mei_hbm_me_cl_add(struct mei_device *dev, * * @dev: the device structure * - * returns 0 on success and < 0 on failure + * Return: 0 on success and < 0 on failure */ static int mei_hbm_prop_req(struct mei_device *dev) @@ -405,7 +405,7 @@ static int mei_hbm_prop_req(struct mei_device *dev) * @dev: the device structure * @pg_cmd: the pg command code * - * returns -EIO on write failure + * Return: -EIO on write failure * -EOPNOTSUPP if the operation is not supported by the protocol */ int mei_hbm_pg(struct mei_device *dev, u8 pg_cmd) @@ -434,10 +434,9 @@ EXPORT_SYMBOL_GPL(mei_hbm_pg); /** * mei_hbm_stop_req - send stop request message * - * @dev - mei device - * @cl: client info + * @dev: mei device * - * This function returns -EIO on write failure + * Return: -EIO on write failure */ static int mei_hbm_stop_req(struct mei_device *dev) { @@ -461,7 +460,7 @@ static int mei_hbm_stop_req(struct mei_device *dev) * @dev: the device structure * @cl: client info * - * This function returns -EIO on write failure + * Return: -EIO on write failure */ int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl) { @@ -477,7 +476,7 @@ int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl) * @dev: the device structure * @flow: flow control. * - * return 0 on success, < 0 otherwise + * Return: 0 on success, < 0 otherwise */ static int mei_hbm_add_single_flow_creds(struct mei_device *dev, struct hbm_flow_control *flow) @@ -533,7 +532,7 @@ static void mei_hbm_cl_flow_control_res(struct mei_device *dev, * @dev: the device structure * @cl: a client to disconnect from * - * This function returns -EIO on write failure + * Return: -EIO on write failure */ int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl) { @@ -548,7 +547,7 @@ int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl) * @dev: the device structure * @cl: a client to disconnect from * - * This function returns -EIO on write failure + * Return: -EIO on write failure */ int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl) { @@ -584,7 +583,7 @@ static void mei_hbm_cl_disconnect_res(struct mei_cl *cl, * @dev: the device structure * @cl: a client to connect to * - * returns -EIO on write failure + * Return: -EIO on write failure */ int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl) { @@ -677,7 +676,7 @@ static void mei_hbm_cl_res(struct mei_device *dev, * @dev: the device structure. * @disconnect_req: disconnect request bus message from the me * - * returns -ENOMEM on allocation failure + * Return: -ENOMEM on allocation failure */ static int mei_hbm_fw_disconnect_req(struct mei_device *dev, struct hbm_client_connect_request *disconnect_req) @@ -702,7 +701,7 @@ static int mei_hbm_fw_disconnect_req(struct mei_device *dev, } /** - * mei_hbm_config_features: check what hbm features and commands + * mei_hbm_config_features - check what hbm features and commands * are supported by the fw * * @dev: the device structure @@ -724,7 +723,7 @@ static void mei_hbm_config_features(struct mei_device *dev) * support the hbm version of the device * * @dev: the device structure - * returns true if driver can support hbm version of the device + * Return: true if driver can support hbm version of the device */ bool mei_hbm_version_is_supported(struct mei_device *dev) { @@ -738,9 +737,9 @@ bool mei_hbm_version_is_supported(struct mei_device *dev) * handle the read bus message cmd processing. * * @dev: the device structure - * @mei_hdr: header of bus message + * @hdr: header of bus message * - * returns 0 on success and < 0 on failure + * Return: 0 on success and < 0 on failure */ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) { diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 77166ea30a4d..9dd7aa70bd85 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -28,10 +28,10 @@ /** * mei_me_reg_read - Reads 32bit data from the mei device * - * @dev: the device structure + * @hw: the me hardware structure * @offset: offset from which to read the data * - * returns register value (u32) + * Return: register value (u32) */ static inline u32 mei_me_reg_read(const struct mei_me_hw *hw, unsigned long offset) @@ -43,7 +43,7 @@ static inline u32 mei_me_reg_read(const struct mei_me_hw *hw, /** * mei_me_reg_write - Writes 32bit data to the mei device * - * @dev: the device structure + * @hw: the me hardware structure * @offset: offset from which to write the data * @value: register value to write (u32) */ @@ -59,7 +59,7 @@ static inline void mei_me_reg_write(const struct mei_me_hw *hw, * * @dev: the device structure * - * returns ME_CB_RW register value (u32) + * Return: ME_CB_RW register value (u32) */ static u32 mei_me_mecbrw_read(const struct mei_device *dev) { @@ -68,9 +68,9 @@ static u32 mei_me_mecbrw_read(const struct mei_device *dev) /** * mei_me_mecsr_read - Reads 32bit data from the ME CSR * - * @dev: the device structure + * @hw: the me hardware structure * - * returns ME_CSR_HA register value (u32) + * Return: ME_CSR_HA register value (u32) */ static inline u32 mei_me_mecsr_read(const struct mei_me_hw *hw) { @@ -80,9 +80,9 @@ static inline u32 mei_me_mecsr_read(const struct mei_me_hw *hw) /** * mei_hcsr_read - Reads 32bit data from the host CSR * - * @dev: the device structure + * @hw: the me hardware structure * - * returns H_CSR register value (u32) + * Return: H_CSR register value (u32) */ static inline u32 mei_hcsr_read(const struct mei_me_hw *hw) { @@ -93,7 +93,7 @@ static inline u32 mei_hcsr_read(const struct mei_me_hw *hw) * mei_hcsr_set - writes H_CSR register to the mei device, * and ignores the H_IS bit for it is write-one-to-zero. * - * @dev: the device structure + * @hw: the me hardware structure */ static inline void mei_hcsr_set(struct mei_me_hw *hw, u32 hcsr) { @@ -274,8 +274,8 @@ static void mei_me_host_set_ready(struct mei_device *dev) /** * mei_me_host_is_ready - check whether the host has turned ready * - * @dev - mei device - * returns bool + * @dev: mei device + * Return: bool */ static bool mei_me_host_is_ready(struct mei_device *dev) { @@ -288,8 +288,8 @@ static bool mei_me_host_is_ready(struct mei_device *dev) /** * mei_me_hw_is_ready - check whether the me(hw) has turned ready * - * @dev - mei device - * returns bool + * @dev: mei device + * Return: bool */ static bool mei_me_hw_is_ready(struct mei_device *dev) { @@ -333,7 +333,7 @@ static int mei_me_hw_start(struct mei_device *dev) * * @dev: the device structure * - * returns number of filled slots + * Return: number of filled slots */ static unsigned char mei_hbuf_filled_slots(struct mei_device *dev) { @@ -353,7 +353,7 @@ static unsigned char mei_hbuf_filled_slots(struct mei_device *dev) * * @dev: the device structure * - * returns true if empty, false - otherwise. + * Return: true if empty, false - otherwise. */ static bool mei_me_hbuf_is_empty(struct mei_device *dev) { @@ -365,7 +365,7 @@ static bool mei_me_hbuf_is_empty(struct mei_device *dev) * * @dev: the device structure * - * returns -EOVERFLOW if overflow, otherwise empty slots count + * Return: -EOVERFLOW if overflow, otherwise empty slots count */ static int mei_me_hbuf_empty_slots(struct mei_device *dev) { @@ -394,7 +394,7 @@ static size_t mei_me_hbuf_max_len(const struct mei_device *dev) * @header: mei HECI header of message * @buf: message payload will be written * - * This function returns -EIO if write has failed + * Return: -EIO if write has failed */ static int mei_me_write_message(struct mei_device *dev, struct mei_msg_hdr *header, @@ -444,7 +444,7 @@ static int mei_me_write_message(struct mei_device *dev, * * @dev: the device structure * - * returns -EOVERFLOW if overflow, otherwise filled slots count + * Return: -EOVERFLOW if overflow, otherwise filled slots count */ static int mei_me_count_full_read_slots(struct mei_device *dev) { @@ -529,7 +529,7 @@ static void mei_me_pg_exit(struct mei_device *dev) * * @dev: the device structure * - * returns 0 on success an error code otherwise + * Return: 0 on success an error code otherwise */ int mei_me_pg_set_sync(struct mei_device *dev) { @@ -566,7 +566,7 @@ int mei_me_pg_set_sync(struct mei_device *dev) * * @dev: the device structure * - * returns 0 on success an error code otherwise + * Return: 0 on success an error code otherwise */ int mei_me_pg_unset_sync(struct mei_device *dev) { @@ -603,7 +603,7 @@ reply: * * @dev: the device structure * - * returns: true is pg supported, false otherwise + * Return: true is pg supported, false otherwise */ static bool mei_me_pg_is_enabled(struct mei_device *dev) { @@ -635,7 +635,7 @@ notsupported: * @irq: The irq number * @dev_id: pointer to the device structure * - * returns irqreturn_t + * Return: irqreturn_t */ irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id) @@ -660,7 +660,7 @@ irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id) * @irq: The irq number * @dev_id: pointer to the device structure * - * returns irqreturn_t + * Return: irqreturn_t * */ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) @@ -841,7 +841,7 @@ const struct mei_cfg mei_me_lpt_cfg = { * @pdev: The pci device structure * @cfg: per device generation config * - * returns The mei_device_device pointer on success, NULL on failure. + * Return: The mei_device_device pointer on success, NULL on failure. */ struct mei_device *mei_me_dev_init(struct pci_dev *pdev, const struct mei_cfg *cfg) diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index 695d480e44dc..0a155228645b 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c @@ -85,7 +85,7 @@ static inline u32 mei_txe_sec_reg_read(struct mei_txe_hw *hw, * mei_txe_sec_reg_write_silent - Writes 32bit data to the SeC BAR * doesn't check for aliveness * - * @dev: the device structure + * @hw: the txe hardware structure * @offset: register offset * @value: value to write * @@ -100,7 +100,7 @@ static inline void mei_txe_sec_reg_write_silent(struct mei_txe_hw *hw, /** * mei_txe_sec_reg_write - Writes 32bit data to the SeC BAR * - * @dev: the device structure + * @hw: the txe hardware structure * @offset: register offset * @value: value to write * @@ -128,7 +128,7 @@ static inline u32 mei_txe_br_reg_read(struct mei_txe_hw *hw, /** * mei_txe_br_reg_write - Writes 32bit data to the Bridge BAR * - * @hw: the device structure + * @hw: the txe hardware structure * @offset: offset from which to write the data * @value: the byte to write */ @@ -205,7 +205,8 @@ static u32 mei_txe_aliveness_get(struct mei_device *dev) * @expected: expected aliveness value * * Polls for HICR_HOST_ALIVENESS_RESP.ALIVENESS_RESP to be set - * returns > 0 if the expected value was received, -ETIME otherwise + * + * Return: > 0 if the expected value was received, -ETIME otherwise */ static int mei_txe_aliveness_poll(struct mei_device *dev, u32 expected) { @@ -238,7 +239,8 @@ static int mei_txe_aliveness_poll(struct mei_device *dev, u32 expected) * @expected: expected aliveness value * * Waits for HICR_HOST_ALIVENESS_RESP.ALIVENESS_RESP to be set - * returns returns 0 on success and < 0 otherwise + * + * Return: 0 on success and < 0 otherwise */ static int mei_txe_aliveness_wait(struct mei_device *dev, u32 expected) { @@ -277,7 +279,7 @@ static int mei_txe_aliveness_wait(struct mei_device *dev, u32 expected) * * @dev: the device structure * - * returns returns 0 on success and < 0 otherwise + * Return: 0 on success and < 0 otherwise */ int mei_txe_aliveness_set_sync(struct mei_device *dev, u32 req) { @@ -291,7 +293,7 @@ int mei_txe_aliveness_set_sync(struct mei_device *dev, u32 req) * * @dev: the device structure * - * returns: true is pg supported, false otherwise + * Return: true is pg supported, false otherwise */ static bool mei_txe_pg_is_enabled(struct mei_device *dev) { @@ -304,7 +306,7 @@ static bool mei_txe_pg_is_enabled(struct mei_device *dev) * * @dev: the device structure * - * returns: MEI_PG_OFF if aliveness is on and MEI_PG_ON otherwise + * Return: MEI_PG_OFF if aliveness is on and MEI_PG_ON otherwise */ static inline enum mei_pg_state mei_txe_pg_state(struct mei_device *dev) { @@ -329,9 +331,10 @@ static void mei_txe_input_ready_interrupt_enable(struct mei_device *dev) } /** - * mei_txe_input_doorbell_set - * - Sets bit 0 in SEC_IPC_INPUT_DOORBELL.IPC_INPUT_DOORBELL. - * @dev: the device structure + * mei_txe_input_doorbell_set - sets bit 0 in + * SEC_IPC_INPUT_DOORBELL.IPC_INPUT_DOORBELL. + * + * @hw: the txe hardware structure */ static void mei_txe_input_doorbell_set(struct mei_txe_hw *hw) { @@ -343,7 +346,7 @@ static void mei_txe_input_doorbell_set(struct mei_txe_hw *hw) /** * mei_txe_output_ready_set - Sets the SICR_SEC_IPC_OUTPUT_STATUS bit to 1 * - * @dev: the device structure + * @hw: the txe hardware structure */ static void mei_txe_output_ready_set(struct mei_txe_hw *hw) { @@ -459,7 +462,7 @@ static void mei_txe_input_payload_write(struct mei_device *dev, * @dev: the device structure * @idx: index in the device buffer * - * returns register value at index + * Return: register value at index */ static u32 mei_txe_out_data_read(const struct mei_device *dev, unsigned long idx) @@ -503,6 +506,8 @@ static void mei_txe_readiness_clear(struct mei_device *dev) * the HICR_SEC_IPC_READINESS register value * * @dev: the device structure + * + * Return: the HICR_SEC_IPC_READINESS register value */ static u32 mei_txe_readiness_get(struct mei_device *dev) { @@ -553,7 +558,7 @@ static inline bool mei_txe_host_is_ready(struct mei_device *dev) * * @dev: the device structure * - * returns 0 on success and -ETIME on timeout + * Return: 0 on success and -ETIME on timeout */ static int mei_txe_readiness_wait(struct mei_device *dev) { @@ -637,7 +642,8 @@ static void mei_txe_hw_config(struct mei_device *dev) * @dev: the device structure * @header: header of message * @buf: message buffer will be written - * returns 1 if success, 0 - otherwise. + * + * Return: if success, 0 - otherwise. */ static int mei_txe_write(struct mei_device *dev, @@ -704,7 +710,7 @@ static int mei_txe_write(struct mei_device *dev, * * @dev: the device structure * - * returns the PAYLOAD_SIZE - 4 + * Return: PAYLOAD_SIZE - 4 */ static size_t mei_txe_hbuf_max_len(const struct mei_device *dev) { @@ -716,7 +722,7 @@ static size_t mei_txe_hbuf_max_len(const struct mei_device *dev) * * @dev: the device structure * - * returns always hbuf_depth + * Return: always hbuf_depth */ static int mei_txe_hbuf_empty_slots(struct mei_device *dev) { @@ -730,7 +736,7 @@ static int mei_txe_hbuf_empty_slots(struct mei_device *dev) * * @dev: the device structure * - * returns always buffer size in dwords count + * Return: always buffer size in dwords count */ static int mei_txe_count_full_read_slots(struct mei_device *dev) { @@ -743,7 +749,7 @@ static int mei_txe_count_full_read_slots(struct mei_device *dev) * * @dev: the device structure * - * returns mei message header + * Return: mei message header */ static u32 mei_txe_read_hdr(const struct mei_device *dev) @@ -757,7 +763,7 @@ static u32 mei_txe_read_hdr(const struct mei_device *dev) * @buf: message buffer will be written * @len: message size will be read * - * returns -EINVAL on error wrong argument and 0 on success + * Return: -EINVAL on error wrong argument and 0 on success */ static int mei_txe_read(struct mei_device *dev, unsigned char *buf, unsigned long len) @@ -799,7 +805,7 @@ static int mei_txe_read(struct mei_device *dev, * @dev: the device structure * @intr_enable: if interrupt should be enabled after reset. * - * returns 0 on success and < 0 in case of error + * Return: 0 on success and < 0 in case of error */ static int mei_txe_hw_reset(struct mei_device *dev, bool intr_enable) { @@ -853,7 +859,7 @@ static int mei_txe_hw_reset(struct mei_device *dev, bool intr_enable) * * @dev: the device structure * - * returns 0 on success and < 0 in case of error + * Return: 0 on success and < 0 in case of error */ static int mei_txe_hw_start(struct mei_device *dev) { @@ -964,7 +970,8 @@ out: * @irq: The irq number * @dev_id: pointer to the device structure * - * returns irqreturn_t + * Return: IRQ_WAKE_THREAD if interrupt is designed for the device + * IRQ_NONE otherwise */ irqreturn_t mei_txe_irq_quick_handler(int irq, void *dev_id) { @@ -982,7 +989,7 @@ irqreturn_t mei_txe_irq_quick_handler(int irq, void *dev_id) * @irq: The irq number * @dev_id: pointer to the device structure * - * returns irqreturn_t + * Return: IRQ_HANDLED * */ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id) @@ -1130,7 +1137,7 @@ static const struct mei_hw_ops mei_txe_hw_ops = { * * @pdev - pci device * - * returns struct mei_device * on success or NULL; + * Return: struct mei_device * on success or NULL; * */ struct mei_device *mei_txe_dev_init(struct pci_dev *pdev) diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h index 6e31113b63df..ea8de2a88b31 100644 --- a/drivers/misc/mei/hw.h +++ b/drivers/misc/mei/hw.h @@ -99,16 +99,16 @@ enum mei_stop_reason_types { /** - * mei_hbm_status - mei host bus messages return values + * enum mei_hbm_status - mei host bus messages return values * - * @MEI_HBMS_SUCCESS - status success - * @MEI_HBMS_CLIENT_NOT_FOUND - client not found - * @MEI_HBMS_ALREADY_EXISTS - connection already established - * @MEI_HBMS_REJECTED - connection is rejected - * @MEI_HBMS_INVALID_PARAMETER - invalid parameter - * @MEI_HBMS_NOT_ALLOWED - operation not allowed - * @MEI_HBMS_ALREADY_STARTED - system is already started - * @MEI_HBMS_NOT_STARTED - system not started + * @MEI_HBMS_SUCCESS : status success + * @MEI_HBMS_CLIENT_NOT_FOUND : client not found + * @MEI_HBMS_ALREADY_EXISTS : connection already established + * @MEI_HBMS_REJECTED : connection is rejected + * @MEI_HBMS_INVALID_PARAMETER : invalid parameter + * @MEI_HBMS_NOT_ALLOWED : operation not allowed + * @MEI_HBMS_ALREADY_STARTED : system is already started + * @MEI_HBMS_NOT_STARTED : system not started */ enum mei_hbm_status { MEI_HBMS_SUCCESS = 0, @@ -165,10 +165,10 @@ struct mei_bus_message { * struct hbm_cl_cmd - client specific host bus command * CONNECT, DISCONNECT, and FlOW CONTROL * - * @hbm_cmd - bus message command header - * @me_addr - address of the client in ME - * @host_addr - address of the client in the driver - * @data + * @hbm_cmd: bus message command header + * @me_addr: address of the client in ME + * @host_addr: address of the client in the driver + * @data: generic data */ struct mei_hbm_cl_cmd { u8 hbm_cmd; @@ -248,8 +248,8 @@ struct hbm_props_response { /** * struct hbm_power_gate - power gate request/response * - * @hbm_cmd - bus message command header - * @reserved[3] + * @hbm_cmd: bus message command header + * @reserved: reserved */ struct hbm_power_gate { u8 hbm_cmd; @@ -259,10 +259,10 @@ struct hbm_power_gate { /** * struct hbm_client_connect_request - connect/disconnect request * - * @hbm_cmd - bus message command header - * @me_addr - address of the client in ME - * @host_addr - address of the client in the driver - * @reserved + * @hbm_cmd: bus message command header + * @me_addr: address of the client in ME + * @host_addr: address of the client in the driver + * @reserved: reserved */ struct hbm_client_connect_request { u8 hbm_cmd; @@ -274,10 +274,10 @@ struct hbm_client_connect_request { /** * struct hbm_client_connect_response - connect/disconnect response * - * @hbm_cmd - bus message command header - * @me_addr - address of the client in ME - * @host_addr - address of the client in the driver - * @status - status of the request + * @hbm_cmd: bus message command header + * @me_addr: address of the client in ME + * @host_addr: address of the client in the driver + * @status: status of the request */ struct hbm_client_connect_response { u8 hbm_cmd; diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 76ef8ffa42c1..52d7f425ff8d 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -56,11 +56,11 @@ const char *mei_pg_state_str(enum mei_pg_state state) /** - * mei_cancel_work. Cancel mei background jobs + * mei_cancel_work - Cancel mei background jobs * * @dev: the device structure * - * returns 0 on success or < 0 if the reset hasn't succeeded + * Return: 0 on success or < 0 if the reset hasn't succeeded */ void mei_cancel_work(struct mei_device *dev) { @@ -175,7 +175,7 @@ EXPORT_SYMBOL_GPL(mei_reset); * * @dev: the device structure * - * returns 0 on success, <0 on failure. + * Return: 0 on success, <0 on failure. */ int mei_start(struct mei_device *dev) { @@ -244,7 +244,7 @@ EXPORT_SYMBOL_GPL(mei_start); * * @dev: the device structure * - * returns 0 on success or -ENODEV if the restart hasn't succeeded + * Return: 0 on success or -ENODEV if the restart hasn't succeeded */ int mei_restart(struct mei_device *dev) { @@ -325,7 +325,7 @@ EXPORT_SYMBOL_GPL(mei_stop); * * @dev: the device structure * - * returns true of there is no pending write + * Return: true of there is no pending write */ bool mei_write_is_idle(struct mei_device *dev) { diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 8844e1772793..d8aa1d372f74 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -33,8 +33,8 @@ * mei_irq_compl_handler - dispatch complete handlers * for the completed callbacks * - * @dev - mei device - * @compl_list - list of completed cbs + * @dev: mei device + * @compl_list: list of completed cbs */ void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *compl_list) { @@ -62,7 +62,7 @@ EXPORT_SYMBOL_GPL(mei_irq_compl_handler); * @cl: host client * @mei_hdr: header of mei client message * - * returns true if matches, false otherwise + * Return: true if matches, false otherwise */ static inline int mei_cl_hbm_equal(struct mei_cl *cl, struct mei_msg_hdr *mei_hdr) @@ -72,12 +72,12 @@ static inline int mei_cl_hbm_equal(struct mei_cl *cl, } /** * mei_cl_is_reading - checks if the client - is the one to read this message + * is the one to read this message * * @cl: mei client * @mei_hdr: header of mei message * - * returns true on match and false otherwise + * Return: true on match and false otherwise */ static bool mei_cl_is_reading(struct mei_cl *cl, struct mei_msg_hdr *mei_hdr) { @@ -93,7 +93,7 @@ static bool mei_cl_is_reading(struct mei_cl *cl, struct mei_msg_hdr *mei_hdr) * @mei_hdr: header of mei client message * @complete_list: An instance of our list structure * - * returns 0 on success, <0 on failure. + * Return: 0 on success, <0 on failure. */ static int mei_cl_irq_read_msg(struct mei_device *dev, struct mei_msg_hdr *mei_hdr, @@ -165,7 +165,7 @@ static int mei_cl_irq_read_msg(struct mei_device *dev, * @cb: callback block. * @cmpl_list: complete list. * - * returns 0, OK; otherwise, error. + * Return: 0, OK; otherwise, error. */ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) @@ -201,7 +201,7 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb, * @cb: callback block. * @cmpl_list: complete list. * - * returns 0, OK; otherwise, error. + * Return: 0, OK; otherwise, error. */ static int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) @@ -241,7 +241,7 @@ static int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb, * @cb: callback block. * @cmpl_list: complete list. * - * returns 0, OK; otherwise, error. + * Return: 0, OK; otherwise, error. */ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) @@ -278,7 +278,7 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb, * @cb: callback block. * @cmpl_list: complete list. * - * returns 0, OK; otherwise, error. + * Return: 0, OK; otherwise, error. */ static int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) @@ -321,7 +321,7 @@ static int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, * @cmpl_list: An instance of our list structure * @slots: slots to read. * - * returns 0 on success, <0 on failure. + * Return: 0 on success, <0 on failure. */ int mei_irq_read_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list, s32 *slots) @@ -424,7 +424,7 @@ EXPORT_SYMBOL_GPL(mei_irq_read_handler); * @dev: the device structure * @cmpl_list: An instance of our list structure * - * returns 0 on success, <0 on failure. + * Return: 0 on success, <0 on failure. */ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) { diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index d31f271f6516..beedc91f03a6 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -44,7 +44,7 @@ * @inode: pointer to inode structure * @file: pointer to file structure * - * returns 0 on success, <0 on error + * Return: 0 on success, <0 on error */ static int mei_open(struct inode *inode, struct file *file) { @@ -96,7 +96,7 @@ err_unlock: * @inode: pointer to inode structure * @file: pointer to file structure * - * returns 0 on success, <0 on error + * Return: 0 on success, <0 on error */ static int mei_release(struct inode *inode, struct file *file) { @@ -157,7 +157,7 @@ out: * @length: buffer length * @offset: data offset in buffer * - * returns >=0 data length on success , <0 on error + * Return: >=0 data length on success , <0 on error */ static ssize_t mei_read(struct file *file, char __user *ubuf, size_t length, loff_t *offset) @@ -297,7 +297,7 @@ out: * @length: buffer length * @offset: data offset in buffer * - * returns >=0 data length on success , <0 on error + * Return: >=0 data length on success , <0 on error */ static ssize_t mei_write(struct file *file, const char __user *ubuf, size_t length, loff_t *offset) @@ -414,13 +414,12 @@ out: /** * mei_ioctl_connect_client - the connect to fw client IOCTL function * - * @dev: the device structure - * @data: IOCTL connect data, input and output parameters * @file: private data of the file object + * @data: IOCTL connect data, input and output parameters * * Locking: called under "dev->device_lock" lock * - * returns 0 on success, <0 on failure. + * Return: 0 on success, <0 on failure. */ static int mei_ioctl_connect_client(struct file *file, struct mei_connect_client_data *data) @@ -509,7 +508,7 @@ end: * @cmd: ioctl command * @data: pointer to mei message structure * - * returns 0 on success , <0 on error + * Return: 0 on success , <0 on error */ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) { @@ -573,7 +572,7 @@ out: * @cmd: ioctl command * @data: pointer to mei message structure * - * returns 0 on success , <0 on error + * Return: 0 on success , <0 on error */ #ifdef CONFIG_COMPAT static long mei_compat_ioctl(struct file *file, @@ -590,7 +589,7 @@ static long mei_compat_ioctl(struct file *file, * @file: pointer to file structure * @wait: pointer to poll_table structure * - * returns poll mask + * Return: poll mask */ static unsigned int mei_poll(struct file *file, poll_table *wait) { @@ -660,7 +659,7 @@ static DEFINE_IDR(mei_idr); * * @dev: device pointer * - * returns allocated minor, or -ENOSPC if no free minor left + * Return: allocated minor, or -ENOSPC if no free minor left */ static int mei_minor_get(struct mei_device *dev) { diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 0a1f2b735706..563eebb62827 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -157,8 +157,8 @@ struct mei_msg_data { /* * struct mei_fw_status - storage of FW status data * - * @count - number of actually available elements in array - * @status - FW status registers + * @count: number of actually available elements in array + * @status: FW status registers */ struct mei_fw_status { int count; @@ -168,9 +168,10 @@ struct mei_fw_status { /** * struct mei_me_client - representation of me (fw) client * - * @props - client properties - * @client_id - me client id - * @mei_flow_ctrl_creds - flow control credits + * @list: link in me client list + * @props: client properties + * @client_id: me client id + * @mei_flow_ctrl_creds: flow control credits */ struct mei_me_client { struct list_head list; @@ -185,8 +186,9 @@ struct mei_cl; /** * struct mei_cl_cb - file operation callback structure * - * @cl - file client who is running this operation - * @fop_type - file operation type + * @list: link in callback queue + * @cl: file client who is running this operation + * @fop_type: file operation type */ struct mei_cl_cb { struct list_head list; @@ -226,31 +228,31 @@ struct mei_cl { /** struct mei_hw_ops * - * @host_is_ready - query for host readiness + * @host_is_ready : query for host readiness - * @hw_is_ready - query if hw is ready - * @hw_reset - reset hw - * @hw_start - start hw after reset - * @hw_config - configure hw + * @hw_is_ready : query if hw is ready + * @hw_reset : reset hw + * @hw_start : start hw after reset + * @hw_config : configure hw - * @fw_status - get fw status registers - * @pg_state - power gating state of the device - * @pg_is_enabled - is power gating enabled + * @fw_status : get fw status registers + * @pg_state : power gating state of the device + * @pg_is_enabled : is power gating enabled - * @intr_clear - clear pending interrupts - * @intr_enable - enable interrupts - * @intr_disable - disable interrupts + * @intr_clear : clear pending interrupts + * @intr_enable : enable interrupts + * @intr_disable : disable interrupts - * @hbuf_free_slots - query for write buffer empty slots - * @hbuf_is_ready - query if write buffer is empty - * @hbuf_max_len - query for write buffer max len + * @hbuf_free_slots : query for write buffer empty slots + * @hbuf_is_ready : query if write buffer is empty + * @hbuf_max_len : query for write buffer max len - * @write - write a message to FW + * @write : write a message to FW - * @rdbuf_full_slots - query how many slots are filled + * @rdbuf_full_slots : query how many slots are filled - * @read_hdr - get first 4 bytes (header) - * @read - read a buffer from the FW + * @read_hdr : get first 4 bytes (header) + * @read : read a buffer from the FW */ struct mei_hw_ops { @@ -330,7 +332,6 @@ void mei_cl_bus_exit(void); * when being probed and shall use it for doing ME bus I/O. * * @dev: linux driver model device pointer - * @uuid: me client uuid * @cl: mei client * @ops: ME transport ops * @event_cb: Drivers register this callback to get asynchronous ME @@ -383,21 +384,21 @@ const char *mei_pg_state_str(enum mei_pg_state state); /** * struct mei_device - MEI private device struct - * @dev - device on a bus - * @cdev - character device - * @minor - minor number allocated for device + * @dev : device on a bus + * @cdev : character device + * @minor : minor number allocated for device * - * @reset_count - limits the number of consecutive resets - * @hbm_state - state of host bus message protocol + * @reset_count : limits the number of consecutive resets + * @hbm_state : state of host bus message protocol * - * @hbm_f_pg_supported - hbm feature pgi protocol + * @hbm_f_pg_supported : hbm feature pgi protocol * - * @pg_event - power gating event - * @mem_addr - mem mapped base register address + * @pg_event : power gating event + * @mem_addr : mem mapped base register address - * @hbuf_depth - depth of hardware host/write buffer is slots - * @hbuf_is_ready - query if the host host/write buffer is ready - * @wr_msg - the buffer for hbm control messages + * @hbuf_depth : depth of hardware host/write buffer is slots + * @hbuf_is_ready : query if the host host/write buffer is ready + * @wr_msg : the buffer for hbm control messages */ struct mei_device { struct device *dev; @@ -521,8 +522,9 @@ static inline unsigned long mei_secs_to_jiffies(unsigned long sec) /** * mei_data2slots - get slots - number of (dwords) from a message length * + size of the mei header - * @length - size of the messages in bytes - * returns - number of slots + * @length: size of the messages in bytes + * + * Return: number of slots */ static inline u32 mei_data2slots(size_t length) { @@ -531,8 +533,8 @@ static inline u32 mei_data2slots(size_t length) /** * mei_slots2data- get data in slots - bytes from slots - * @slots - number of available slots - * returns - number of bytes in slots + * @slots: number of available slots + * Return: number of bytes in slots */ static inline u32 mei_slots2data(int slots) { @@ -610,12 +612,12 @@ int mei_wd_host_init(struct mei_device *dev); /* * mei_watchdog_register - Registering watchdog interface * once we got connection to the WD Client - * @dev - mei device + * @dev: mei device */ int mei_watchdog_register(struct mei_device *dev); /* * mei_watchdog_unregister - Unregistering watchdog interface - * @dev - mei device + * @dev: mei device */ void mei_watchdog_unregister(struct mei_device *dev); diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c index 5b369f4c47de..288665eb4862 100644 --- a/drivers/misc/mei/nfc.c +++ b/drivers/misc/mei/nfc.c @@ -88,7 +88,8 @@ struct mei_nfc_hci_hdr { #define MEI_NFC_HEADER_SIZE 10 -/** mei_nfc_dev - NFC mei device +/** + * struct mei_nfc_dev - NFC mei device * * @cl: NFC host client * @cl_info: NFC info host client diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index a91071716868..532d39300498 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -103,7 +103,7 @@ static inline void mei_me_unset_pm_domain(struct mei_device *dev) {} * @pdev: PCI device structure * @cfg: per generation config * - * returns true if ME Interface is valid, false otherwise + * Return: true if ME Interface is valid, false otherwise */ static bool mei_me_quirk_probe(struct pci_dev *pdev, const struct mei_cfg *cfg) @@ -122,7 +122,7 @@ static bool mei_me_quirk_probe(struct pci_dev *pdev, * @pdev: PCI device structure * @ent: entry in kcs_pci_tbl * - * returns 0 on success, <0 on failure. + * Return: 0 on success, <0 on failure. */ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { diff --git a/drivers/misc/mei/pci-txe.c b/drivers/misc/mei/pci-txe.c index 69eb999ae803..2898480ae33f 100644 --- a/drivers/misc/mei/pci-txe.c +++ b/drivers/misc/mei/pci-txe.c @@ -67,7 +67,7 @@ static void mei_txe_pci_iounmap(struct pci_dev *pdev, struct mei_txe_hw *hw) * @pdev: PCI device structure * @ent: entry in mei_txe_pci_tbl * - * returns 0 on success, <0 on failure. + * Return: 0 on success, <0 on failure. */ static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 626b4c13993b..b836dfffceb5 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -51,7 +51,7 @@ static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout) * * @dev: the device structure * - * returns -ENOTTY if wd client cannot be found + * Return: -ENOTTY if wd client cannot be found * -EIO if write has failed * 0 on success */ @@ -105,7 +105,7 @@ int mei_wd_host_init(struct mei_device *dev) * * @dev: the device structure * - * returns 0 if success, + * Return: 0 if success, * -EIO when message send fails * -EINVAL when invalid message is to be sent * -ENODEV on flow control failure @@ -150,9 +150,8 @@ int mei_wd_send(struct mei_device *dev) * mei_wd_stop - sends watchdog stop message to fw. * * @dev: the device structure - * @preserve: indicate if to keep the timeout value * - * returns 0 if success + * Return: 0 if success * on error: * -EIO when message send fails * -EINVAL when invalid message is to be sent @@ -207,7 +206,7 @@ err: * * @wd_dev - watchdog device struct * - * returns 0 if success, negative errno code for failure + * Return: 0 if success, negative errno code for failure */ static int mei_wd_ops_start(struct watchdog_device *wd_dev) { @@ -244,7 +243,7 @@ end_unlock: * * @wd_dev - watchdog device struct * - * returns 0 if success, negative errno code for failure + * Return: 0 if success, negative errno code for failure */ static int mei_wd_ops_stop(struct watchdog_device *wd_dev) { @@ -266,7 +265,7 @@ static int mei_wd_ops_stop(struct watchdog_device *wd_dev) * * @wd_dev - watchdog device struct * - * returns 0 if success, negative errno code for failure + * Return: 0 if success, negative errno code for failure */ static int mei_wd_ops_ping(struct watchdog_device *wd_dev) { @@ -314,7 +313,7 @@ end: * @wd_dev - watchdog device struct * @timeout - timeout value to set * - * returns 0 if success, negative errno code for failure + * Return: 0 if success, negative errno code for failure */ static int mei_wd_ops_set_timeout(struct watchdog_device *wd_dev, unsigned int timeout) -- cgit v1.2.3 From ce23139c6c2ee92d5eace20f6f10d716cf295a5b Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Mon, 29 Sep 2014 16:31:50 +0300 Subject: mei: fix kernel-doc warnings Add missed parameters descriptions and return values descriptions Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 5 +- drivers/misc/mei/client.c | 6 ++ drivers/misc/mei/debugfs.c | 2 + drivers/misc/mei/hbm.c | 2 + drivers/misc/mei/hw-me.c | 41 ++++++++++-- drivers/misc/mei/hw-me.h | 6 ++ drivers/misc/mei/hw-txe.c | 63 ++++++++++++------ drivers/misc/mei/hw-txe.h | 1 + drivers/misc/mei/hw.h | 2 + drivers/misc/mei/init.c | 4 +- drivers/misc/mei/interrupt.c | 4 +- drivers/misc/mei/mei_dev.h | 151 +++++++++++++++++++++++++++++++++---------- drivers/misc/mei/nfc.c | 5 ++ drivers/misc/mei/pci-me.c | 6 +- 14 files changed, 231 insertions(+), 67 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 29b3fd0ab505..6cdce8477f57 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -64,6 +64,7 @@ void mei_amthif_reset_params(struct mei_device *dev) * * @dev: the device structure * + * Return: 0 on success, <0 on failure. */ int mei_amthif_host_init(struct mei_device *dev) { @@ -352,7 +353,7 @@ int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb) return mei_amthif_send_cmd(dev, cb); } /** - * mei_amthif_run_next_cmd + * mei_amthif_run_next_cmd - send next amt command from queue * * @dev: the device structure */ @@ -496,7 +497,7 @@ int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, } /** - * mei_amthif_irq_read_message - read routine after ISR to + * mei_amthif_irq_read_msg - read routine after ISR to * handle the read amthif message * * @dev: the device structure diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 1f91c55f7af5..bc9ba5359bc6 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -271,6 +271,8 @@ int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length) * mei_cl_flush_queues - flushes queue lists belonging to cl. * * @cl: host client + * + * Return: 0 on success, -EINVAL if cl or cl->dev is NULL. */ int mei_cl_flush_queues(struct mei_cl *cl) { @@ -402,6 +404,8 @@ int mei_cl_link(struct mei_cl *cl, int id) * mei_cl_unlink - remove me_cl from the list * * @cl: host client + * + * Return: always 0 */ int mei_cl_unlink(struct mei_cl *cl) { @@ -756,6 +760,7 @@ int mei_cl_flow_ctrl_reduce(struct mei_cl *cl) * mei_cl_read_start - the start read client message function. * * @cl: host client + * @length: number of bytes to read * * Return: 0 on success, <0 on failure. */ @@ -916,6 +921,7 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, * * @cl: host client * @cb: write callback with filled data + * @blocking: block until completed * * Return: number of bytes sent on success, <0 on failure. */ diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index 357b02c18d40..ce1566715f80 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c @@ -177,6 +177,8 @@ void mei_dbgfs_deregister(struct mei_device *dev) * * @dev: the mei device structure * @name: the mei device name + * + * Return: 0 on success, <0 on failure. */ int mei_dbgfs_register(struct mei_device *dev, const char *name) { diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index da476e8cac84..49a2653d91a5 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -176,6 +176,8 @@ void mei_hbm_cl_hdr(struct mei_cl *cl, u8 hbm_cmd, void *buf, size_t len) * @cl: client * @hbm_cmd: host bus message command * @len: buffer length + * + * Return: 0 on success, <0 on failure. */ static inline int mei_hbm_cl_write(struct mei_device *dev, diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 9dd7aa70bd85..4f2fd6fc1e23 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -94,6 +94,7 @@ static inline u32 mei_hcsr_read(const struct mei_me_hw *hw) * and ignores the H_IS bit for it is write-one-to-zero. * * @hw: the me hardware structure + * @hcsr: new register value */ static inline void mei_hcsr_set(struct mei_me_hw *hw, u32 hcsr) { @@ -106,6 +107,8 @@ static inline void mei_hcsr_set(struct mei_me_hw *hw, u32 hcsr) * * @dev: mei device * @fw_status: fw status register values + * + * Return: 0 on success, error otherwise */ static int mei_me_fw_status(struct mei_device *dev, struct mei_fw_status *fw_status) @@ -149,8 +152,9 @@ static void mei_me_hw_config(struct mei_device *dev) * mei_me_pg_state - translate internal pg state * to the mei power gating state * - * @hw - me hardware - * returns: MEI_PG_OFF if aliveness is on and MEI_PG_ON otherwise + * @dev: mei device + * + * Return: MEI_PG_OFF if aliveness is on and MEI_PG_ON otherwise */ static inline enum mei_pg_state mei_me_pg_state(struct mei_device *dev) { @@ -160,7 +164,7 @@ static inline enum mei_pg_state mei_me_pg_state(struct mei_device *dev) } /** - * mei_clear_interrupts - clear and stop interrupts + * mei_me_intr_clear - clear and stop interrupts * * @dev: the device structure */ @@ -187,7 +191,7 @@ static void mei_me_intr_enable(struct mei_device *dev) } /** - * mei_disable_interrupts - disables mei device interrupts + * mei_me_intr_disable - disables mei device interrupts * * @dev: the device structure */ @@ -222,6 +226,8 @@ static void mei_me_hw_reset_release(struct mei_device *dev) * * @dev: the device structure * @intr_enable: if interrupt should be enabled after reset. + * + * Return: always 0 */ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable) { @@ -259,10 +265,8 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable) /** * mei_me_host_set_ready - enable device * - * @dev - mei device - * returns bool + * @dev: mei device */ - static void mei_me_host_set_ready(struct mei_device *dev) { struct mei_me_hw *hw = to_me_hw(dev); @@ -271,6 +275,7 @@ static void mei_me_host_set_ready(struct mei_device *dev) hw->host_hw_state |= H_IE | H_IG | H_RDY; mei_hcsr_set(hw, hw->host_hw_state); } + /** * mei_me_host_is_ready - check whether the host has turned ready * @@ -299,6 +304,13 @@ static bool mei_me_hw_is_ready(struct mei_device *dev) return (hw->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA; } +/** + * mei_me_hw_ready_wait - wait until the me(hw) has turned ready + * or timeout is reached + * + * @dev: mei device + * Return: 0 on success, error otherwise + */ static int mei_me_hw_ready_wait(struct mei_device *dev) { mutex_unlock(&dev->device_lock); @@ -315,6 +327,12 @@ static int mei_me_hw_ready_wait(struct mei_device *dev) return 0; } +/** + * mei_me_hw_start - hw start routine + * + * @dev: mei device + * Return: 0 on success, error otherwise + */ static int mei_me_hw_start(struct mei_device *dev) { int ret = mei_me_hw_ready_wait(dev); @@ -381,6 +399,13 @@ static int mei_me_hbuf_empty_slots(struct mei_device *dev) return empty_slots; } +/** + * mei_me_hbuf_max_len - returns size of hw buffer. + * + * @dev: the device structure + * + * Return: size of hw buffer in bytes + */ static size_t mei_me_hbuf_max_len(const struct mei_device *dev) { return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr); @@ -472,6 +497,8 @@ static int mei_me_count_full_read_slots(struct mei_device *dev) * @dev: the device structure * @buffer: message buffer will be written * @buffer_length: message size will be read + * + * Return: always 0 */ static int mei_me_read_slots(struct mei_device *dev, unsigned char *buffer, unsigned long buffer_length) diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h index b0001b3a0fb5..e6a59a62573a 100644 --- a/drivers/misc/mei/hw-me.h +++ b/drivers/misc/mei/hw-me.h @@ -47,7 +47,13 @@ struct mei_cfg { #define MEI_ME_RPM_TIMEOUT 500 /* ms */ /** + * struct mei_me_hw - me hw specific data + * * @cfg: per device generation config and ops + * @mem_addr: io memory address + * @host_hw_state: cached host state + * @me_hw_state: cached me (fw) state + * @pg_state: power gating state */ struct mei_me_hw { const struct mei_cfg *cfg; diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index 0a155228645b..d3cf042fc509 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c @@ -28,11 +28,12 @@ #include "hbm.h" /** - * mei_txe_reg_read - Reads 32bit data from the device + * mei_txe_reg_read - Reads 32bit data from the txe device * * @base_addr: registers base address * @offset: register offset * + * Return: register value */ static inline u32 mei_txe_reg_read(void __iomem *base_addr, unsigned long offset) @@ -41,7 +42,7 @@ static inline u32 mei_txe_reg_read(void __iomem *base_addr, } /** - * mei_txe_reg_write - Writes 32bit data to the device + * mei_txe_reg_write - Writes 32bit data to the txe device * * @base_addr: registers base address * @offset: register offset @@ -56,10 +57,12 @@ static inline void mei_txe_reg_write(void __iomem *base_addr, /** * mei_txe_sec_reg_read_silent - Reads 32bit data from the SeC BAR * - * @dev: the device structure + * @hw: the txe hardware structure * @offset: register offset * * Doesn't check for aliveness while Reads 32bit data from the SeC BAR + * + * Return: register value */ static inline u32 mei_txe_sec_reg_read_silent(struct mei_txe_hw *hw, unsigned long offset) @@ -70,10 +73,12 @@ static inline u32 mei_txe_sec_reg_read_silent(struct mei_txe_hw *hw, /** * mei_txe_sec_reg_read - Reads 32bit data from the SeC BAR * - * @dev: the device structure + * @hw: the txe hardware structure * @offset: register offset * * Reads 32bit data from the SeC BAR and shout loud if aliveness is not set + * + * Return: register value */ static inline u32 mei_txe_sec_reg_read(struct mei_txe_hw *hw, unsigned long offset) @@ -115,9 +120,10 @@ static inline void mei_txe_sec_reg_write(struct mei_txe_hw *hw, /** * mei_txe_br_reg_read - Reads 32bit data from the Bridge BAR * - * @hw: the device structure + * @hw: the txe hardware structure * @offset: offset from which to read the data * + * Return: the byte read. */ static inline u32 mei_txe_br_reg_read(struct mei_txe_hw *hw, unsigned long offset) @@ -147,7 +153,10 @@ static inline void mei_txe_br_reg_write(struct mei_txe_hw *hw, * Request for aliveness change and returns true if the change is * really needed and false if aliveness is already * in the requested state - * Requires device lock to be held + * + * Locking: called under "dev->device_lock" lock + * + * Return: true if request was send */ static bool mei_txe_aliveness_set(struct mei_device *dev, u32 req) { @@ -172,6 +181,8 @@ static bool mei_txe_aliveness_set(struct mei_device *dev, u32 req) * * Extract HICR_HOST_ALIVENESS_RESP_ACK bit from * from HICR_HOST_ALIVENESS_REQ register value + * + * Return: SICR_HOST_ALIVENESS_REQ_REQUESTED bit value */ static u32 mei_txe_aliveness_req_get(struct mei_device *dev) { @@ -184,10 +195,11 @@ static u32 mei_txe_aliveness_req_get(struct mei_device *dev) /** * mei_txe_aliveness_get - get aliveness response register value + * * @dev: the device structure * - * Extract HICR_HOST_ALIVENESS_RESP_ACK bit - * from HICR_HOST_ALIVENESS_RESP register value + * Return: HICR_HOST_ALIVENESS_RESP_ACK bit from HICR_HOST_ALIVENESS_RESP + * register */ static u32 mei_txe_aliveness_get(struct mei_device *dev) { @@ -278,6 +290,7 @@ static int mei_txe_aliveness_wait(struct mei_device *dev, u32 expected) * mei_txe_aliveness_set_sync - sets an wait for aliveness to complete * * @dev: the device structure + * @req: requested aliveness value * * Return: 0 on success and < 0 otherwise */ @@ -359,6 +372,8 @@ static void mei_txe_output_ready_set(struct mei_txe_hw *hw) * mei_txe_is_input_ready - check if TXE is ready for receiving data * * @dev: the device structure + * + * Return: true if INPUT STATUS READY bit is set */ static bool mei_txe_is_input_ready(struct mei_device *dev) { @@ -417,6 +432,8 @@ static void mei_txe_intr_enable(struct mei_device *dev) * * Checks if there are pending interrupts * only Aliveness, Readiness, Input ready, and Output doorbell are relevant + * + * Return: true if there are pending interrupts */ static bool mei_txe_pending_interrupts(struct mei_device *dev) { @@ -476,7 +493,7 @@ static u32 mei_txe_out_data_read(const struct mei_device *dev, /* Readiness */ /** - * mei_txe_readiness_set_host_rdy + * mei_txe_readiness_set_host_rdy - set host readiness bit * * @dev: the device structure */ @@ -490,7 +507,7 @@ static void mei_txe_readiness_set_host_rdy(struct mei_device *dev) } /** - * mei_txe_readiness_clear + * mei_txe_readiness_clear - clear host readiness bit * * @dev: the device structure */ @@ -521,7 +538,9 @@ static u32 mei_txe_readiness_get(struct mei_device *dev) * mei_txe_readiness_is_sec_rdy - check readiness * for HICR_SEC_IPC_READINESS_SEC_RDY * - * @readiness - cached readiness state + * @readiness: cached readiness state + * + * Return: true if readiness bit is set */ static inline bool mei_txe_readiness_is_sec_rdy(u32 readiness) { @@ -532,6 +551,8 @@ static inline bool mei_txe_readiness_is_sec_rdy(u32 readiness) * mei_txe_hw_is_ready - check if the hw is ready * * @dev: the device structure + * + * Return: true if sec is ready */ static bool mei_txe_hw_is_ready(struct mei_device *dev) { @@ -544,6 +565,8 @@ static bool mei_txe_hw_is_ready(struct mei_device *dev) * mei_txe_host_is_ready - check if the host is ready * * @dev: the device structure + * + * Return: true if host is ready */ static inline bool mei_txe_host_is_ready(struct mei_device *dev) { @@ -589,6 +612,8 @@ const struct mei_fw_status mei_txe_fw_sts = { * * @dev: mei device * @fw_status: fw status register values + * + * Return: 0 on success, error otherwise */ static int mei_txe_fw_status(struct mei_device *dev, struct mei_fw_status *fw_status) @@ -643,7 +668,7 @@ static void mei_txe_hw_config(struct mei_device *dev) * @header: header of message * @buf: message buffer will be written * - * Return: if success, 0 - otherwise. + * Return: 0 if success, <0 - otherwise. */ static int mei_txe_write(struct mei_device *dev, @@ -710,7 +735,7 @@ static int mei_txe_write(struct mei_device *dev, * * @dev: the device structure * - * Return: PAYLOAD_SIZE - 4 + * Return: the PAYLOAD_SIZE - 4 */ static size_t mei_txe_hbuf_max_len(const struct mei_device *dev) { @@ -859,7 +884,7 @@ static int mei_txe_hw_reset(struct mei_device *dev, bool intr_enable) * * @dev: the device structure * - * Return: 0 on success and < 0 in case of error + * Return: 0 on success an error code otherwise */ static int mei_txe_hw_start(struct mei_device *dev) { @@ -915,6 +940,8 @@ static int mei_txe_hw_start(struct mei_device *dev) * * @dev: the device structure * @do_ack: acknowledge interrupts + * + * Return: true if found interrupts to process. */ static bool mei_txe_check_and_ack_intrs(struct mei_device *dev, bool do_ack) { @@ -990,7 +1017,6 @@ irqreturn_t mei_txe_irq_quick_handler(int irq, void *dev_id) * @dev_id: pointer to the device structure * * Return: IRQ_HANDLED - * */ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id) { @@ -1135,10 +1161,9 @@ static const struct mei_hw_ops mei_txe_hw_ops = { /** * mei_txe_dev_init - allocates and initializes txe hardware specific structure * - * @pdev - pci device - * - * Return: struct mei_device * on success or NULL; + * @pdev: pci device * + * Return: struct mei_device * on success or NULL */ struct mei_device *mei_txe_dev_init(struct pci_dev *pdev) { @@ -1165,6 +1190,8 @@ struct mei_device *mei_txe_dev_init(struct pci_dev *pdev) * @dev: the device structure * @addr: physical address start of the range * @range: physical range size + * + * Return: 0 on success an error code otherwise */ int mei_txe_setup_satt2(struct mei_device *dev, phys_addr_t addr, u32 range) { diff --git a/drivers/misc/mei/hw-txe.h b/drivers/misc/mei/hw-txe.h index e8dd2d165c25..ce3ed0b88b0c 100644 --- a/drivers/misc/mei/hw-txe.h +++ b/drivers/misc/mei/hw-txe.h @@ -40,6 +40,7 @@ * @mem_addr: SeC and BRIDGE bars * @aliveness: aliveness (power gating) state of the hardware * @readiness: readiness state of the hardware + * @slots: number of empty slots * @wait_aliveness_resp: aliveness wait queue * @intr_cause: translated interrupt cause */ diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h index ea8de2a88b31..16fef6dc4dd7 100644 --- a/drivers/misc/mei/hw.h +++ b/drivers/misc/mei/hw.h @@ -109,6 +109,8 @@ enum mei_stop_reason_types { * @MEI_HBMS_NOT_ALLOWED : operation not allowed * @MEI_HBMS_ALREADY_STARTED : system is already started * @MEI_HBMS_NOT_STARTED : system not started + * + * @MEI_HBMS_MAX : sentinel */ enum mei_hbm_status { MEI_HBMS_SUCCESS = 0, diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 52d7f425ff8d..7901d076c127 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -59,8 +59,6 @@ const char *mei_pg_state_str(enum mei_pg_state state) * mei_cancel_work - Cancel mei background jobs * * @dev: the device structure - * - * Return: 0 on success or < 0 if the reset hasn't succeeded */ void mei_cancel_work(struct mei_device *dev) { @@ -75,6 +73,8 @@ EXPORT_SYMBOL_GPL(mei_cancel_work); * mei_reset - resets host and fw. * * @dev: the device structure + * + * Return: 0 on success or < 0 if the reset hasn't succeeded */ int mei_reset(struct mei_device *dev) { diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index d8aa1d372f74..20c6c511f438 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -87,7 +87,7 @@ static bool mei_cl_is_reading(struct mei_cl *cl, struct mei_msg_hdr *mei_hdr) } /** - * mei_irq_read_client_message - process client message + * mei_cl_irq_read_msg - process client message * * @dev: the device structure * @mei_hdr: header of mei client message @@ -234,7 +234,7 @@ static int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb, /** - * mei_cl_irq_close - processes client read related operation from the + * mei_cl_irq_read - processes client read related operation from the * interrupt thread context - request for flow control credits * * @cl: client diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 563eebb62827..71744b16cc8c 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -129,11 +129,11 @@ enum mei_wd_states { /** * enum mei_cb_file_ops - file operation associated with the callback - * @MEI_FOP_READ - read - * @MEI_FOP_WRITE - write - * @MEI_FOP_CONNECT - connect - * @MEI_FOP_DISCONNECT - disconnect - * @MEI_FOP_DISCONNECT_RSP - disconnect response + * @MEI_FOP_READ: read + * @MEI_FOP_WRITE: write + * @MEI_FOP_CONNECT: connect + * @MEI_FOP_DISCONNECT: disconnect + * @MEI_FOP_DISCONNECT_RSP: disconnect response */ enum mei_cb_file_ops { MEI_FOP_READ = 0, @@ -189,6 +189,12 @@ struct mei_cl; * @list: link in callback queue * @cl: file client who is running this operation * @fop_type: file operation type + * @request_buffer: buffer to store request data + * @response_buffer: buffer to store response data + * @buf_idx: last read index + * @read_time: last read operation time stamp (iamthif) + * @file_object: pointer to file structure + * @internal: communication between driver and FW flag */ struct mei_cl_cb { struct list_head list; @@ -202,7 +208,29 @@ struct mei_cl_cb { u32 internal:1; }; -/* MEI client instance carried as file->private_data*/ +/** + * struct mei_cl - me client host representation + * carried in file->private_data + * + * @link: link in the clients list + * @dev: mei parent device + * @state: file operation state + * @tx_wait: wait queue for tx completion + * @rx_wait: wait queue for rx completion + * @wait: wait queue for management operation + * @status: connection status + * @cl_uuid: client uuid name + * @host_client_id: host id + * @me_client_id: me/fw id + * @mei_flow_ctrl_creds: transmit flow credentials + * @timer_count: watchdog timer for operation completion + * @reading_state: state of the rx + * @writing_state: state of the tx + * @read_cb: current pending reading callback + * + * @device: device on the mei client bus + * @device_link: link to bus clients + */ struct mei_cl { struct list_head link; struct mei_device *dev; @@ -211,7 +239,6 @@ struct mei_cl { wait_queue_head_t rx_wait; wait_queue_head_t wait; int status; - /* ID of client connected */ uuid_le cl_uuid; u8 host_client_id; u8 me_client_id; @@ -334,8 +361,10 @@ void mei_cl_bus_exit(void); * @dev: linux driver model device pointer * @cl: mei client * @ops: ME transport ops + * @event_work: async work to execute event callback * @event_cb: Drivers register this callback to get asynchronous ME * events (e.g. Rx buffer pending) notifications. + * @event_context: event callback run context * @events: Events bitmask sent to the driver. * @priv_data: client private data */ @@ -355,7 +384,7 @@ struct mei_cl_device { }; - /** +/** * enum mei_pg_event - power gating transition events * * @MEI_PG_EVENT_IDLE: the driver is not in power gating transition @@ -383,49 +412,102 @@ const char *mei_pg_state_str(enum mei_pg_state state); /** * struct mei_device - MEI private device struct - + * * @dev : device on a bus * @cdev : character device * @minor : minor number allocated for device * - * @reset_count : limits the number of consecutive resets - * @hbm_state : state of host bus message protocol + * @read_list : read completion list + * @write_list : write pending list + * @write_waiting_list : write completion list + * @ctrl_wr_list : pending control write list + * @ctrl_rd_list : pending control read list * - * @hbm_f_pg_supported : hbm feature pgi protocol + * @file_list : list of opened handles + * @open_handle_count: number of opened handles + * + * @device_lock : big device lock + * @timer_work : MEI timer delayed work (timeouts) + * + * @recvd_hw_ready : hw ready message received flag + * + * @wait_hw_ready : wait queue for receive HW ready message form FW + * @wait_pg : wait queue for receive PG message from FW + * @wait_hbm_start : wait queue for receive HBM start message from FW + * @wait_stop_wd : wait queue for receive WD stop message from FW + * + * @reset_count : number of consecutive resets + * @dev_state : device state + * @hbm_state : state of host bus message protocol + * @init_clients_timer : HBM init handshake timeout * * @pg_event : power gating event - * @mem_addr : mem mapped base register address - + * @pg_domain : runtime PM domain + * + * @rd_msg_buf : control messages buffer + * @rd_msg_hdr : read message header storage + * * @hbuf_depth : depth of hardware host/write buffer is slots * @hbuf_is_ready : query if the host host/write buffer is ready * @wr_msg : the buffer for hbm control messages + * + * @version : HBM protocol version in use + * @hbm_f_pg_supported : hbm feature pgi protocol + * + * @me_clients : list of FW clients + * @me_clients_map : FW clients bit map + * @host_clients_map : host clients id pool + * @me_client_index : last FW client index in enumeration + * + * @wd_cl : watchdog client + * @wd_state : watchdog client state + * @wd_pending : watchdog command is pending + * @wd_timeout : watchdog expiration timeout + * @wd_data : watchdog message buffer + * + * @amthif_cmd_list : amthif list for cmd waiting + * @amthif_rd_complete_list : amthif list for reading completed cmd data + * @iamthif_file_object : file for current amthif operation + * @iamthif_cl : amthif host client + * @iamthif_current_cb : amthif current operation callback + * @iamthif_open_count : number of opened amthif connections + * @iamthif_mtu : amthif client max message length + * @iamthif_timer : time stamp of current amthif command completion + * @iamthif_stall_timer : timer to detect amthif hang + * @iamthif_msg_buf : amthif current message buffer + * @iamthif_msg_buf_size : size of current amthif message request buffer + * @iamthif_msg_buf_index : current index in amthif message request buffer + * @iamthif_state : amthif processor state + * @iamthif_flow_control_pending: amthif waits for flow control + * @iamthif_ioctl : wait for completion if amthif control message + * @iamthif_canceled : current amthif command is canceled + * + * @init_work : work item for the device init + * @reset_work : work item for the device reset + * + * @device_list : mei client bus list + * + * @dbgfs_dir : debugfs mei root directory + * + * @ops: : hw specific operations + * @hw : hw specific data */ struct mei_device { struct device *dev; struct cdev cdev; int minor; - /* - * lists of queues - */ - /* array of pointers to aio lists */ - struct mei_cl_cb read_list; /* driver read queue */ - struct mei_cl_cb write_list; /* driver write queue */ - struct mei_cl_cb write_waiting_list; /* write waiting queue */ - struct mei_cl_cb ctrl_wr_list; /* managed write IOCTL list */ - struct mei_cl_cb ctrl_rd_list; /* managed read IOCTL list */ + struct mei_cl_cb read_list; + struct mei_cl_cb write_list; + struct mei_cl_cb write_waiting_list; + struct mei_cl_cb ctrl_wr_list; + struct mei_cl_cb ctrl_rd_list; - /* - * list of files - */ struct list_head file_list; long open_handle_count; - /* - * lock for the device - */ - struct mutex device_lock; /* device lock */ - struct delayed_work timer_work; /* MEI timer delayed work (timeouts) */ + struct mutex device_lock; + struct delayed_work timer_work; bool recvd_hw_ready; /* @@ -452,7 +534,7 @@ struct mei_device { struct dev_pm_domain pg_domain; #endif /* CONFIG_PM_RUNTIME */ - unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */ + unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; u32 rd_msg_hdr; /* write buffer */ @@ -522,6 +604,7 @@ static inline unsigned long mei_secs_to_jiffies(unsigned long sec) /** * mei_data2slots - get slots - number of (dwords) from a message length * + size of the mei header + * * @length: size of the messages in bytes * * Return: number of slots @@ -532,8 +615,10 @@ static inline u32 mei_data2slots(size_t length) } /** - * mei_slots2data- get data in slots - bytes from slots + * mei_slots2data - get data in slots - bytes from slots + * * @slots: number of available slots + * * Return: number of bytes in slots */ static inline u32 mei_slots2data(int slots) diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c index 288665eb4862..622654323177 100644 --- a/drivers/misc/mei/nfc.c +++ b/drivers/misc/mei/nfc.c @@ -94,9 +94,14 @@ struct mei_nfc_hci_hdr { * @cl: NFC host client * @cl_info: NFC info host client * @init_work: perform connection to the info client + * @send_wq: send completion wait queue * @fw_ivn: NFC Interface Version Number * @vendor_id: NFC manufacturer ID * @radio_type: NFC radio type + * @bus_name: bus name + * + * @req_id: message counter + * @recv_req_id: reception message counter */ struct mei_nfc_dev { struct mei_cl *cl; diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 532d39300498..badd4d8d2135 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -98,7 +98,7 @@ static inline void mei_me_unset_pm_domain(struct mei_device *dev) {} #endif /* CONFIG_PM_RUNTIME */ /** - * mei_quirk_probe - probe for devices that doesn't valid ME interface + * mei_me_quirk_probe - probe for devices that doesn't valid ME interface * * @pdev: PCI device structure * @cfg: per generation config @@ -117,7 +117,7 @@ static bool mei_me_quirk_probe(struct pci_dev *pdev, } /** - * mei_probe - Device Initialization Routine + * mei_me_probe - Device Initialization Routine * * @pdev: PCI device structure * @ent: entry in kcs_pci_tbl @@ -249,7 +249,7 @@ end: } /** - * mei_remove - Device Removal Routine + * mei_me_remove - Device Removal Routine * * @pdev: PCI device structure * -- cgit v1.2.3 From 480bd3c4ad30558dd26c16e3f8358e36522d9af0 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Mon, 29 Sep 2014 18:21:46 -0700 Subject: mei: mei_txe_fw_sts can be static CC: Tomas Winkler Signed-off-by: Fengguang Wu Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-txe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index d3cf042fc509..c5e1902e493f 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c @@ -601,7 +601,7 @@ static int mei_txe_readiness_wait(struct mei_device *dev) return 0; } -const struct mei_fw_status mei_txe_fw_sts = { +static const struct mei_fw_status mei_txe_fw_sts = { .count = 2, .status[0] = PCI_CFG_TXE_FW_STS0, .status[1] = PCI_CFG_TXE_FW_STS1 -- cgit v1.2.3