Merge tag 'char-misc-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver patches from Greg Kroah-Hartman: "Here's the big char/misc driver patches for 3.9-rc1. Nothing major here, just lots of different driver updates (mei, hyperv, ipack, extcon, vmci, etc.). All of these have been in the linux-next tree for a while." * tag 'char-misc-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (209 commits) w1: w1_therm: Add force-pullup option for "broken" sensors w1: ds2482: Added 1-Wire pull-up support to the driver vme: add missing put_device() after device_register() fails extcon: max8997: Use workqueue to check cable state after completing boot of platform extcon: max8997: Set default UART/USB path on probe extcon: max8997: Consolidate duplicate code for checking ADC/CHG cable type extcon: max8997: Set default of ADC debounce time during initialization extcon: max8997: Remove duplicate code related to set H/W line path extcon: max8997: Move defined constant to header file extcon: max77693: Make max77693_extcon_cable static extcon: max8997: Remove unreachable code extcon: max8997: Make max8997_extcon_cable static extcon: max77693: Remove unnecessary goto statement to improve readability extcon: max77693: Convert to devm_input_allocate_device() extcon: gpio: Rename filename of extcon-gpio.c according to kernel naming style CREDITS: update email and address of Harald Hoyer extcon: arizona: Use MICDET for final microphone identification extcon: arizona: Always take the first HPDET reading as the final one extcon: arizona: Clear _trig_sts bits after jack detection extcon: arizona: Don't HPDET magic when headphones are enabled ...
此提交包含在:
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/platform_device.h>
|
||||
@@ -459,43 +460,34 @@ static int ds1wm_probe(struct platform_device *pdev)
|
||||
if (!pdev)
|
||||
return -ENODEV;
|
||||
|
||||
ds1wm_data = kzalloc(sizeof(*ds1wm_data), GFP_KERNEL);
|
||||
ds1wm_data = devm_kzalloc(&pdev->dev, sizeof(*ds1wm_data), GFP_KERNEL);
|
||||
if (!ds1wm_data)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, ds1wm_data);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
ret = -ENXIO;
|
||||
goto err0;
|
||||
}
|
||||
ds1wm_data->map = ioremap(res->start, resource_size(res));
|
||||
if (!ds1wm_data->map) {
|
||||
ret = -ENOMEM;
|
||||
goto err0;
|
||||
}
|
||||
if (!res)
|
||||
return -ENXIO;
|
||||
ds1wm_data->map = devm_ioremap(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!ds1wm_data->map)
|
||||
return -ENOMEM;
|
||||
|
||||
/* calculate bus shift from mem resource */
|
||||
ds1wm_data->bus_shift = resource_size(res) >> 3;
|
||||
|
||||
ds1wm_data->pdev = pdev;
|
||||
ds1wm_data->cell = mfd_get_cell(pdev);
|
||||
if (!ds1wm_data->cell) {
|
||||
ret = -ENODEV;
|
||||
goto err1;
|
||||
}
|
||||
if (!ds1wm_data->cell)
|
||||
return -ENODEV;
|
||||
plat = pdev->dev.platform_data;
|
||||
if (!plat) {
|
||||
ret = -ENODEV;
|
||||
goto err1;
|
||||
}
|
||||
if (!plat)
|
||||
return -ENODEV;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!res) {
|
||||
ret = -ENXIO;
|
||||
goto err1;
|
||||
}
|
||||
if (!res)
|
||||
return -ENXIO;
|
||||
ds1wm_data->irq = res->start;
|
||||
ds1wm_data->int_en_reg_none = (plat->active_high ? DS1WM_INTEN_IAS : 0);
|
||||
ds1wm_data->reset_recover_delay = plat->reset_recover_delay;
|
||||
@@ -505,10 +497,10 @@ static int ds1wm_probe(struct platform_device *pdev)
|
||||
if (res->flags & IORESOURCE_IRQ_LOWEDGE)
|
||||
irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING);
|
||||
|
||||
ret = request_irq(ds1wm_data->irq, ds1wm_isr,
|
||||
ret = devm_request_irq(&pdev->dev, ds1wm_data->irq, ds1wm_isr,
|
||||
IRQF_DISABLED | IRQF_SHARED, "ds1wm", ds1wm_data);
|
||||
if (ret)
|
||||
goto err1;
|
||||
return ret;
|
||||
|
||||
ds1wm_up(ds1wm_data);
|
||||
|
||||
@@ -516,17 +508,12 @@ static int ds1wm_probe(struct platform_device *pdev)
|
||||
|
||||
ret = w1_add_master_device(&ds1wm_master);
|
||||
if (ret)
|
||||
goto err2;
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
err:
|
||||
ds1wm_down(ds1wm_data);
|
||||
free_irq(ds1wm_data->irq, ds1wm_data);
|
||||
err1:
|
||||
iounmap(ds1wm_data->map);
|
||||
err0:
|
||||
kfree(ds1wm_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -560,9 +547,6 @@ static int ds1wm_remove(struct platform_device *pdev)
|
||||
|
||||
w1_remove_master_device(&ds1wm_master);
|
||||
ds1wm_down(ds1wm_data);
|
||||
free_irq(ds1wm_data->irq, ds1wm_data);
|
||||
iounmap(ds1wm_data->map);
|
||||
kfree(ds1wm_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -51,10 +51,10 @@
|
||||
* The top 4 bits always read 0.
|
||||
* To write, the top nibble must be the 1's compl. of the low nibble.
|
||||
*/
|
||||
#define DS2482_REG_CFG_1WS 0x08
|
||||
#define DS2482_REG_CFG_SPU 0x04
|
||||
#define DS2482_REG_CFG_PPM 0x02
|
||||
#define DS2482_REG_CFG_APU 0x01
|
||||
#define DS2482_REG_CFG_1WS 0x08 /* 1-wire speed */
|
||||
#define DS2482_REG_CFG_SPU 0x04 /* strong pull-up */
|
||||
#define DS2482_REG_CFG_PPM 0x02 /* presence pulse masking */
|
||||
#define DS2482_REG_CFG_APU 0x01 /* active pull-up */
|
||||
|
||||
|
||||
/**
|
||||
@@ -131,6 +131,17 @@ struct ds2482_data {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper to calculate values for configuration register
|
||||
* @param conf the raw config value
|
||||
* @return the value w/ complements that can be written to register
|
||||
*/
|
||||
static inline u8 ds2482_calculate_config(u8 conf)
|
||||
{
|
||||
return conf | ((~conf & 0x0f) << 4);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the read pointer.
|
||||
* @param pdev The ds2482 client pointer
|
||||
@@ -399,7 +410,7 @@ static u8 ds2482_w1_reset_bus(void *data)
|
||||
/* If the chip did reset since detect, re-config it */
|
||||
if (err & DS2482_REG_STS_RST)
|
||||
ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG,
|
||||
0xF0);
|
||||
ds2482_calculate_config(0x00));
|
||||
}
|
||||
|
||||
mutex_unlock(&pdev->access_lock);
|
||||
@@ -407,6 +418,32 @@ static u8 ds2482_w1_reset_bus(void *data)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static u8 ds2482_w1_set_pullup(void *data, int delay)
|
||||
{
|
||||
struct ds2482_w1_chan *pchan = data;
|
||||
struct ds2482_data *pdev = pchan->pdev;
|
||||
u8 retval = 1;
|
||||
|
||||
/* if delay is non-zero activate the pullup,
|
||||
* the strong pullup will be automatically deactivated
|
||||
* by the master, so do not explicitly deactive it
|
||||
*/
|
||||
if (delay) {
|
||||
/* both waits are crucial, otherwise devices might not be
|
||||
* powered long enough, causing e.g. a w1_therm sensor to
|
||||
* provide wrong conversion results
|
||||
*/
|
||||
ds2482_wait_1wire_idle(pdev);
|
||||
/* note: it seems like both SPU and APU have to be set! */
|
||||
retval = ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG,
|
||||
ds2482_calculate_config(DS2482_REG_CFG_SPU |
|
||||
DS2482_REG_CFG_APU));
|
||||
ds2482_wait_1wire_idle(pdev);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static int ds2482_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
@@ -452,7 +489,8 @@ static int ds2482_probe(struct i2c_client *client,
|
||||
data->w1_count = 8;
|
||||
|
||||
/* Set all config items to 0 (off) */
|
||||
ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG, 0xF0);
|
||||
ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG,
|
||||
ds2482_calculate_config(0x00));
|
||||
|
||||
mutex_init(&data->access_lock);
|
||||
|
||||
@@ -468,6 +506,7 @@ static int ds2482_probe(struct i2c_client *client,
|
||||
data->w1_ch[idx].w1_bm.touch_bit = ds2482_w1_touch_bit;
|
||||
data->w1_ch[idx].w1_bm.triplet = ds2482_w1_triplet;
|
||||
data->w1_ch[idx].w1_bm.reset_bus = ds2482_w1_reset_bus;
|
||||
data->w1_ch[idx].w1_bm.set_pullup = ds2482_w1_set_pullup;
|
||||
|
||||
err = w1_add_master_device(&data->w1_ch[idx].w1_bm);
|
||||
if (err) {
|
||||
|
@@ -109,34 +109,21 @@ static int mxc_w1_probe(struct platform_device *pdev)
|
||||
struct resource *res;
|
||||
int err = 0;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
|
||||
mdev = kzalloc(sizeof(struct mxc_w1_device), GFP_KERNEL);
|
||||
mdev = devm_kzalloc(&pdev->dev, sizeof(struct mxc_w1_device),
|
||||
GFP_KERNEL);
|
||||
if (!mdev)
|
||||
return -ENOMEM;
|
||||
|
||||
mdev->clk = clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(mdev->clk)) {
|
||||
err = PTR_ERR(mdev->clk);
|
||||
goto failed_clk;
|
||||
}
|
||||
mdev->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(mdev->clk))
|
||||
return PTR_ERR(mdev->clk);
|
||||
|
||||
mdev->clkdiv = (clk_get_rate(mdev->clk) / 1000000) - 1;
|
||||
|
||||
res = request_mem_region(res->start, resource_size(res),
|
||||
"mxc_w1");
|
||||
if (!res) {
|
||||
err = -EBUSY;
|
||||
goto failed_req;
|
||||
}
|
||||
|
||||
mdev->regs = ioremap(res->start, resource_size(res));
|
||||
if (!mdev->regs) {
|
||||
dev_err(&pdev->dev, "Cannot map mxc_w1 registers\n");
|
||||
goto failed_ioremap;
|
||||
}
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mdev->regs = devm_request_and_ioremap(&pdev->dev, res);
|
||||
if (!mdev->regs)
|
||||
return -EBUSY;
|
||||
|
||||
clk_prepare_enable(mdev->clk);
|
||||
__raw_writeb(mdev->clkdiv, mdev->regs + MXC_W1_TIME_DIVIDER);
|
||||
@@ -148,20 +135,10 @@ static int mxc_w1_probe(struct platform_device *pdev)
|
||||
err = w1_add_master_device(&mdev->bus_master);
|
||||
|
||||
if (err)
|
||||
goto failed_add;
|
||||
return err;
|
||||
|
||||
platform_set_drvdata(pdev, mdev);
|
||||
return 0;
|
||||
|
||||
failed_add:
|
||||
iounmap(mdev->regs);
|
||||
failed_ioremap:
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
failed_req:
|
||||
clk_put(mdev->clk);
|
||||
failed_clk:
|
||||
kfree(mdev);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -170,16 +147,10 @@ failed_clk:
|
||||
static int mxc_w1_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mxc_w1_device *mdev = platform_get_drvdata(pdev);
|
||||
struct resource *res;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
w1_remove_master_device(&mdev->bus_master);
|
||||
|
||||
iounmap(mdev->regs);
|
||||
release_mem_region(res->start, resource_size(res));
|
||||
clk_disable_unprepare(mdev->clk);
|
||||
clk_put(mdev->clk);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
|
@@ -72,7 +72,7 @@ static int w1_gpio_probe_dt(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init w1_gpio_probe(struct platform_device *pdev)
|
||||
static int w1_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct w1_bus_master *master;
|
||||
struct w1_gpio_platform_data *pdata;
|
||||
|
@@ -41,14 +41,18 @@ MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature famil
|
||||
* If it was disabled a parasite powered device might not get the require
|
||||
* current to do a temperature conversion. If it is enabled parasite powered
|
||||
* devices have a better chance of getting the current required.
|
||||
* In case the parasite power-detection is not working (seems to be the case
|
||||
* for some DS18S20) the strong pullup can also be forced, regardless of the
|
||||
* power state of the devices.
|
||||
*
|
||||
* Summary of options:
|
||||
* - strong_pullup = 0 Disable strong pullup completely
|
||||
* - strong_pullup = 1 Enable automatic strong pullup detection
|
||||
* - strong_pullup = 2 Force strong pullup
|
||||
*/
|
||||
static int w1_strong_pullup = 1;
|
||||
module_param_named(strong_pullup, w1_strong_pullup, int, 0);
|
||||
|
||||
static u8 bad_roms[][9] = {
|
||||
{0xaa, 0x00, 0x4b, 0x46, 0xff, 0xff, 0x0c, 0x10, 0x87},
|
||||
{}
|
||||
};
|
||||
|
||||
static ssize_t w1_therm_read(struct device *device,
|
||||
struct device_attribute *attr, char *buf);
|
||||
@@ -168,16 +172,6 @@ static inline int w1_convert_temp(u8 rom[9], u8 fid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int w1_therm_check_rom(u8 rom[9])
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<sizeof(bad_roms)/9; ++i)
|
||||
if (!memcmp(bad_roms[i], rom, 9))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t w1_therm_read(struct device *device,
|
||||
struct device_attribute *attr, char *buf)
|
||||
@@ -194,10 +188,11 @@ static ssize_t w1_therm_read(struct device *device,
|
||||
|
||||
memset(rom, 0, sizeof(rom));
|
||||
|
||||
verdict = 0;
|
||||
crc = 0;
|
||||
|
||||
while (max_trying--) {
|
||||
|
||||
verdict = 0;
|
||||
crc = 0;
|
||||
|
||||
if (!w1_reset_select_slave(sl)) {
|
||||
int count = 0;
|
||||
unsigned int tm = 750;
|
||||
@@ -210,7 +205,8 @@ static ssize_t w1_therm_read(struct device *device,
|
||||
continue;
|
||||
|
||||
/* 750ms strong pullup (or delay) after the convert */
|
||||
if (!external_power && w1_strong_pullup)
|
||||
if (w1_strong_pullup == 2 ||
|
||||
(!external_power && w1_strong_pullup))
|
||||
w1_next_pullup(dev, tm);
|
||||
|
||||
w1_write_8(dev, W1_CONVERT_TEMP);
|
||||
@@ -249,7 +245,7 @@ static ssize_t w1_therm_read(struct device *device,
|
||||
}
|
||||
}
|
||||
|
||||
if (!w1_therm_check_rom(rom))
|
||||
if (verdict)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -260,7 +256,7 @@ static ssize_t w1_therm_read(struct device *device,
|
||||
if (verdict)
|
||||
memcpy(sl->rom, rom, sizeof(sl->rom));
|
||||
else
|
||||
dev_warn(device, "18S20 doesn't respond to CONVERT_TEMP.\n");
|
||||
dev_warn(device, "Read failed CRC check\n");
|
||||
|
||||
for (i = 0; i < 9; ++i)
|
||||
c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", sl->rom[i]);
|
||||
|
新增問題並參考
封鎖使用者