diff options
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-aspeed.c | 5 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-designware-platdrv.c | 23 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-designware-slave.c | 6 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-simtec.c | 6 | ||||
| -rw-r--r-- | drivers/i2c/i2c-core-acpi.c | 19 | ||||
| -rw-r--r-- | drivers/i2c/i2c-core-base.c | 5 | ||||
| -rw-r--r-- | drivers/i2c/i2c-core.h | 9 | ||||
| -rw-r--r-- | drivers/i2c/muxes/Kconfig | 2 | 
9 files changed, 56 insertions, 21 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 1006b230b236..65fa29591d21 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -983,7 +983,7 @@ config I2C_UNIPHIER_F  config I2C_VERSATILE  	tristate "ARM Versatile/Realview I2C bus support" -	depends on ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS || COMPILE_TEST +	depends on ARCH_MPS2 || ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS || COMPILE_TEST  	select I2C_ALGOBIT  	help  	  Say yes if you want to support the I2C serial bus on ARMs Versatile diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c index f19348328a71..6fdf9231c23c 100644 --- a/drivers/i2c/busses/i2c-aspeed.c +++ b/drivers/i2c/busses/i2c-aspeed.c @@ -410,10 +410,11 @@ static bool aspeed_i2c_master_irq(struct aspeed_i2c_bus *bus)  	}  	/* We are in an invalid state; reset bus to a known state. */ -	if (!bus->msgs && bus->master_state != ASPEED_I2C_MASTER_STOP) { +	if (!bus->msgs) {  		dev_err(bus->dev, "bus in unknown state");  		bus->cmd_err = -EIO; -		aspeed_i2c_do_stop(bus); +		if (bus->master_state != ASPEED_I2C_MASTER_STOP) +			aspeed_i2c_do_stop(bus);  		goto out_no_complete;  	}  	msg = &bus->msgs[bus->msgs_index]; diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 2ea6d0d25a01..57248bccadbc 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -198,8 +198,7 @@ static void i2c_dw_configure_slave(struct dw_i2c_dev *dev)  	dev->functionality = I2C_FUNC_SLAVE | DW_IC_DEFAULT_FUNCTIONALITY;  	dev->slave_cfg = DW_IC_CON_RX_FIFO_FULL_HLD_CTRL | -			 DW_IC_CON_RESTART_EN | DW_IC_CON_STOP_DET_IFADDRESSED | -			 DW_IC_CON_SPEED_FAST; +			 DW_IC_CON_RESTART_EN | DW_IC_CON_STOP_DET_IFADDRESSED;  	dev->mode = DW_IC_SLAVE; @@ -298,6 +297,9 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)  	}  	acpi_speed = i2c_acpi_find_bus_speed(&pdev->dev); +	/* Some broken DSTDs use 1MiHz instead of 1MHz */ +	if (acpi_speed == 1048576) +		acpi_speed = 1000000;  	/*  	 * Find bus speed from the "clock-frequency" device property, ACPI  	 * or by using fast mode if neither is set. @@ -319,7 +321,8 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)  	if (dev->clk_freq != 100000 && dev->clk_freq != 400000  	    && dev->clk_freq != 1000000 && dev->clk_freq != 3400000) {  		dev_err(&pdev->dev, -			"Only 100kHz, 400kHz, 1MHz and 3.4MHz supported"); +			"%d Hz is unsupported, only 100kHz, 400kHz, 1MHz and 3.4MHz are supported\n", +			dev->clk_freq);  		ret = -EINVAL;  		goto exit_reset;  	} @@ -426,7 +429,7 @@ static void dw_i2c_plat_complete(struct device *dev)  #endif  #ifdef CONFIG_PM -static int dw_i2c_plat_suspend(struct device *dev) +static int dw_i2c_plat_runtime_suspend(struct device *dev)  {  	struct platform_device *pdev = to_platform_device(dev);  	struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev); @@ -448,11 +451,21 @@ static int dw_i2c_plat_resume(struct device *dev)  	return 0;  } +#ifdef CONFIG_PM_SLEEP +static int dw_i2c_plat_suspend(struct device *dev) +{ +	pm_runtime_resume(dev); +	return dw_i2c_plat_runtime_suspend(dev); +} +#endif +  static const struct dev_pm_ops dw_i2c_dev_pm_ops = {  	.prepare = dw_i2c_plat_prepare,  	.complete = dw_i2c_plat_complete,  	SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume) -	SET_RUNTIME_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume, NULL) +	SET_RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend, +			   dw_i2c_plat_resume, +			   NULL)  };  #define DW_I2C_DEV_PMOPS (&dw_i2c_dev_pm_ops) diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c index 0548c7ea578c..78d8fb73927d 100644 --- a/drivers/i2c/busses/i2c-designware-slave.c +++ b/drivers/i2c/busses/i2c-designware-slave.c @@ -177,6 +177,8 @@ static int i2c_dw_reg_slave(struct i2c_client *slave)  		return -EBUSY;  	if (slave->flags & I2C_CLIENT_TEN)  		return -EAFNOSUPPORT; +	pm_runtime_get_sync(dev->dev); +  	/*  	 * Set slave address in the IC_SAR register,  	 * the address to which the DW_apb_i2c responds. @@ -205,6 +207,7 @@ static int i2c_dw_unreg_slave(struct i2c_client *slave)  	dev->disable_int(dev);  	dev->disable(dev);  	dev->slave = NULL; +	pm_runtime_put(dev->dev);  	return 0;  } @@ -272,7 +275,7 @@ static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev)  	slave_activity = ((dw_readl(dev, DW_IC_STATUS) &  		DW_IC_STATUS_SLAVE_ACTIVITY) >> 6); -	if (!enabled || !(raw_stat & ~DW_IC_INTR_ACTIVITY)) +	if (!enabled || !(raw_stat & ~DW_IC_INTR_ACTIVITY) || !dev->slave)  		return 0;  	dev_dbg(dev->dev, @@ -382,7 +385,6 @@ int i2c_dw_probe_slave(struct dw_i2c_dev *dev)  	ret = i2c_add_numbered_adapter(adap);  	if (ret)  		dev_err(dev->dev, "failure adding adapter: %d\n", ret); -	pm_runtime_put_noidle(dev->dev);  	return ret;  } diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c index b4685bb9b5d7..adca51a99487 100644 --- a/drivers/i2c/busses/i2c-simtec.c +++ b/drivers/i2c/busses/i2c-simtec.c @@ -127,8 +127,7 @@ static int simtec_i2c_probe(struct platform_device *dev)  	iounmap(pd->reg);   err_res: -	release_resource(pd->ioarea); -	kfree(pd->ioarea); +	release_mem_region(pd->ioarea->start, size);   err:  	kfree(pd); @@ -142,8 +141,7 @@ static int simtec_i2c_remove(struct platform_device *dev)  	i2c_del_adapter(&pd->adap);  	iounmap(pd->reg); -	release_resource(pd->ioarea); -	kfree(pd->ioarea); +	release_mem_region(pd->ioarea->start, resource_size(pd->ioarea));  	kfree(pd);  	return 0; diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c index 4842ec3a5451..a9126b3cda61 100644 --- a/drivers/i2c/i2c-core-acpi.c +++ b/drivers/i2c/i2c-core-acpi.c @@ -230,6 +230,16 @@ void i2c_acpi_register_devices(struct i2c_adapter *adap)  		dev_warn(&adap->dev, "failed to enumerate I2C slaves\n");  } +const struct acpi_device_id * +i2c_acpi_match_device(const struct acpi_device_id *matches, +		      struct i2c_client *client) +{ +	if (!(client && matches)) +		return NULL; + +	return acpi_match_device(matches, &client->dev); +} +  static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level,  					   void *data, void **return_value)  { @@ -289,7 +299,7 @@ u32 i2c_acpi_find_bus_speed(struct device *dev)  }  EXPORT_SYMBOL_GPL(i2c_acpi_find_bus_speed); -static int i2c_acpi_match_adapter(struct device *dev, void *data) +static int i2c_acpi_find_match_adapter(struct device *dev, void *data)  {  	struct i2c_adapter *adapter = i2c_verify_adapter(dev); @@ -299,7 +309,7 @@ static int i2c_acpi_match_adapter(struct device *dev, void *data)  	return ACPI_HANDLE(dev) == (acpi_handle)data;  } -static int i2c_acpi_match_device(struct device *dev, void *data) +static int i2c_acpi_find_match_device(struct device *dev, void *data)  {  	return ACPI_COMPANION(dev) == data;  } @@ -309,7 +319,7 @@ static struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)  	struct device *dev;  	dev = bus_find_device(&i2c_bus_type, NULL, handle, -			      i2c_acpi_match_adapter); +			      i2c_acpi_find_match_adapter);  	return dev ? i2c_verify_adapter(dev) : NULL;  } @@ -317,7 +327,8 @@ static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev)  {  	struct device *dev; -	dev = bus_find_device(&i2c_bus_type, NULL, adev, i2c_acpi_match_device); +	dev = bus_find_device(&i2c_bus_type, NULL, adev, +			      i2c_acpi_find_match_device);  	return dev ? i2c_verify_client(dev) : NULL;  } diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index c89dac7fd2e7..56e46581b84b 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -353,10 +353,11 @@ static int i2c_device_probe(struct device *dev)  	}  	/* -	 * An I2C ID table is not mandatory, if and only if, a suitable Device -	 * Tree match table entry is supplied for the probing device. +	 * An I2C ID table is not mandatory, if and only if, a suitable OF +	 * or ACPI ID table is supplied for the probing device.  	 */  	if (!driver->id_table && +	    !i2c_acpi_match_device(dev->driver->acpi_match_table, client) &&  	    !i2c_of_match_device(dev->driver->of_match_table, client))  		return -ENODEV; diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h index 3b63f5e5b89c..3d3d9bf02101 100644 --- a/drivers/i2c/i2c-core.h +++ b/drivers/i2c/i2c-core.h @@ -31,9 +31,18 @@ int i2c_check_addr_validity(unsigned addr, unsigned short flags);  int i2c_check_7bit_addr_validity_strict(unsigned short addr);  #ifdef CONFIG_ACPI +const struct acpi_device_id * +i2c_acpi_match_device(const struct acpi_device_id *matches, +		      struct i2c_client *client);  void i2c_acpi_register_devices(struct i2c_adapter *adap);  #else /* CONFIG_ACPI */  static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { } +static inline const struct acpi_device_id * +i2c_acpi_match_device(const struct acpi_device_id *matches, +		      struct i2c_client *client) +{ +	return NULL; +}  #endif /* CONFIG_ACPI */  extern struct notifier_block i2c_acpi_notifier; diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig index 2c64d0e0740f..17121329bb79 100644 --- a/drivers/i2c/muxes/Kconfig +++ b/drivers/i2c/muxes/Kconfig @@ -83,7 +83,7 @@ config I2C_MUX_PINCTRL  	  different sets of pins at run-time.  	  This driver can also be built as a module. If so, the module will be -	  called pinctrl-i2cmux. +	  called i2c-mux-pinctrl.  config I2C_MUX_REG  	tristate "Register-based I2C multiplexer"  | 
