Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "I2C has quite some regression fixes this time. One is also related to watchdogs, we have proper acks from Guenter for them" * 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: acpi: put device when verifying client fails misc: eeprom: at24: fix regulator underflow i2c: gpio: suppress error on probe defer macintosh: windfarm: fix MODINFO regression i2c: designware-pci: Fix BUG_ON during device removal i2c: i801: Do not add ICH_RES_IO_SMI for the iTCO_wdt device watchdog: iTCO_wdt: Make ICH_RES_IO_SMI optional watchdog: iTCO_wdt: Export vendorsupport
This commit is contained in:
commit
d3dca69085
@ -313,6 +313,7 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev)
|
||||
pm_runtime_get_noresume(&pdev->dev);
|
||||
|
||||
i2c_del_adapter(&dev->adapter);
|
||||
devm_free_irq(&pdev->dev, dev->irq, dev);
|
||||
pci_free_irq_vectors(pdev);
|
||||
}
|
||||
|
||||
|
@ -348,7 +348,7 @@ static struct gpio_desc *i2c_gpio_get_desc(struct device *dev,
|
||||
if (ret == -ENOENT)
|
||||
retdesc = ERR_PTR(-EPROBE_DEFER);
|
||||
|
||||
if (ret != -EPROBE_DEFER)
|
||||
if (PTR_ERR(retdesc) != -EPROBE_DEFER)
|
||||
dev_err(dev, "error trying to get descriptor: %d\n", ret);
|
||||
|
||||
return retdesc;
|
||||
|
@ -132,11 +132,6 @@
|
||||
#define TCOBASE 0x050
|
||||
#define TCOCTL 0x054
|
||||
|
||||
#define ACPIBASE 0x040
|
||||
#define ACPIBASE_SMI_OFF 0x030
|
||||
#define ACPICTRL 0x044
|
||||
#define ACPICTRL_EN 0x080
|
||||
|
||||
#define SBREG_BAR 0x10
|
||||
#define SBREG_SMBCTRL 0xc6000c
|
||||
#define SBREG_SMBCTRL_DNV 0xcf000c
|
||||
@ -1553,7 +1548,7 @@ i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev,
|
||||
pci_bus_write_config_byte(pci_dev->bus, devfn, 0xe1, hidden);
|
||||
spin_unlock(&p2sb_spinlock);
|
||||
|
||||
res = &tco_res[ICH_RES_MEM_OFF];
|
||||
res = &tco_res[1];
|
||||
if (pci_dev->device == PCI_DEVICE_ID_INTEL_DNV_SMBUS)
|
||||
res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL_DNV;
|
||||
else
|
||||
@ -1563,7 +1558,7 @@ i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev,
|
||||
res->flags = IORESOURCE_MEM;
|
||||
|
||||
return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1,
|
||||
tco_res, 3, &spt_tco_platform_data,
|
||||
tco_res, 2, &spt_tco_platform_data,
|
||||
sizeof(spt_tco_platform_data));
|
||||
}
|
||||
|
||||
@ -1576,17 +1571,16 @@ static struct platform_device *
|
||||
i801_add_tco_cnl(struct i801_priv *priv, struct pci_dev *pci_dev,
|
||||
struct resource *tco_res)
|
||||
{
|
||||
return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1,
|
||||
tco_res, 2, &cnl_tco_platform_data,
|
||||
sizeof(cnl_tco_platform_data));
|
||||
return platform_device_register_resndata(&pci_dev->dev,
|
||||
"iTCO_wdt", -1, tco_res, 1, &cnl_tco_platform_data,
|
||||
sizeof(cnl_tco_platform_data));
|
||||
}
|
||||
|
||||
static void i801_add_tco(struct i801_priv *priv)
|
||||
{
|
||||
u32 base_addr, tco_base, tco_ctl, ctrl_val;
|
||||
struct pci_dev *pci_dev = priv->pci_dev;
|
||||
struct resource tco_res[3], *res;
|
||||
unsigned int devfn;
|
||||
struct resource tco_res[2], *res;
|
||||
u32 tco_base, tco_ctl;
|
||||
|
||||
/* If we have ACPI based watchdog use that instead */
|
||||
if (acpi_has_watchdog())
|
||||
@ -1601,30 +1595,15 @@ static void i801_add_tco(struct i801_priv *priv)
|
||||
return;
|
||||
|
||||
memset(tco_res, 0, sizeof(tco_res));
|
||||
|
||||
res = &tco_res[ICH_RES_IO_TCO];
|
||||
/*
|
||||
* Always populate the main iTCO IO resource here. The second entry
|
||||
* for NO_REBOOT MMIO is filled by the SPT specific function.
|
||||
*/
|
||||
res = &tco_res[0];
|
||||
res->start = tco_base & ~1;
|
||||
res->end = res->start + 32 - 1;
|
||||
res->flags = IORESOURCE_IO;
|
||||
|
||||
/*
|
||||
* Power Management registers.
|
||||
*/
|
||||
devfn = PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 2);
|
||||
pci_bus_read_config_dword(pci_dev->bus, devfn, ACPIBASE, &base_addr);
|
||||
|
||||
res = &tco_res[ICH_RES_IO_SMI];
|
||||
res->start = (base_addr & ~1) + ACPIBASE_SMI_OFF;
|
||||
res->end = res->start + 3;
|
||||
res->flags = IORESOURCE_IO;
|
||||
|
||||
/*
|
||||
* Enable the ACPI I/O space.
|
||||
*/
|
||||
pci_bus_read_config_dword(pci_dev->bus, devfn, ACPICTRL, &ctrl_val);
|
||||
ctrl_val |= ACPICTRL_EN;
|
||||
pci_bus_write_config_dword(pci_dev->bus, devfn, ACPICTRL, ctrl_val);
|
||||
|
||||
if (priv->features & FEATURE_TCO_CNL)
|
||||
priv->tco_pdev = i801_add_tco_cnl(priv, pci_dev, tco_res);
|
||||
else
|
||||
|
@ -394,9 +394,17 @@ EXPORT_SYMBOL_GPL(i2c_acpi_find_adapter_by_handle);
|
||||
static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev)
|
||||
{
|
||||
struct device *dev;
|
||||
struct i2c_client *client;
|
||||
|
||||
dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev);
|
||||
return dev ? i2c_verify_client(dev) : NULL;
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
client = i2c_verify_client(dev);
|
||||
if (!client)
|
||||
put_device(dev);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,
|
||||
|
@ -312,9 +312,16 @@ static const struct i2c_device_id wf_ad7417_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, wf_ad7417_id);
|
||||
|
||||
static const struct of_device_id wf_ad7417_of_id[] = {
|
||||
{ .compatible = "ad7417", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wf_ad7417_of_id);
|
||||
|
||||
static struct i2c_driver wf_ad7417_driver = {
|
||||
.driver = {
|
||||
.name = "wf_ad7417",
|
||||
.of_match_table = wf_ad7417_of_id,
|
||||
},
|
||||
.probe = wf_ad7417_probe,
|
||||
.remove = wf_ad7417_remove,
|
||||
|
@ -580,9 +580,16 @@ static const struct i2c_device_id wf_fcu_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, wf_fcu_id);
|
||||
|
||||
static const struct of_device_id wf_fcu_of_id[] = {
|
||||
{ .compatible = "fcu", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wf_fcu_of_id);
|
||||
|
||||
static struct i2c_driver wf_fcu_driver = {
|
||||
.driver = {
|
||||
.name = "wf_fcu",
|
||||
.of_match_table = wf_fcu_of_id,
|
||||
},
|
||||
.probe = wf_fcu_probe,
|
||||
.remove = wf_fcu_remove,
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/io.h>
|
||||
@ -91,9 +92,14 @@ static int wf_lm75_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct wf_lm75_sensor *lm;
|
||||
int rc, ds1775 = id->driver_data;
|
||||
int rc, ds1775;
|
||||
const char *name, *loc;
|
||||
|
||||
if (id)
|
||||
ds1775 = id->driver_data;
|
||||
else
|
||||
ds1775 = !!of_device_get_match_data(&client->dev);
|
||||
|
||||
DBG("wf_lm75: creating %s device at address 0x%02x\n",
|
||||
ds1775 ? "ds1775" : "lm75", client->addr);
|
||||
|
||||
@ -164,9 +170,17 @@ static const struct i2c_device_id wf_lm75_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, wf_lm75_id);
|
||||
|
||||
static const struct of_device_id wf_lm75_of_id[] = {
|
||||
{ .compatible = "lm75", .data = (void *)0},
|
||||
{ .compatible = "ds1775", .data = (void *)1 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wf_lm75_of_id);
|
||||
|
||||
static struct i2c_driver wf_lm75_driver = {
|
||||
.driver = {
|
||||
.name = "wf_lm75",
|
||||
.of_match_table = wf_lm75_of_id,
|
||||
},
|
||||
.probe = wf_lm75_probe,
|
||||
.remove = wf_lm75_remove,
|
||||
|
@ -166,9 +166,16 @@ static const struct i2c_device_id wf_lm87_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, wf_lm87_id);
|
||||
|
||||
static const struct of_device_id wf_lm87_of_id[] = {
|
||||
{ .compatible = "lm87cimt", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wf_lm87_of_id);
|
||||
|
||||
static struct i2c_driver wf_lm87_driver = {
|
||||
.driver = {
|
||||
.name = "wf_lm87",
|
||||
.of_match_table = wf_lm87_of_id,
|
||||
},
|
||||
.probe = wf_lm87_probe,
|
||||
.remove = wf_lm87_remove,
|
||||
|
@ -120,9 +120,16 @@ static const struct i2c_device_id wf_max6690_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, wf_max6690_id);
|
||||
|
||||
static const struct of_device_id wf_max6690_of_id[] = {
|
||||
{ .compatible = "max6690", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wf_max6690_of_id);
|
||||
|
||||
static struct i2c_driver wf_max6690_driver = {
|
||||
.driver = {
|
||||
.name = "wf_max6690",
|
||||
.of_match_table = wf_max6690_of_id,
|
||||
},
|
||||
.probe = wf_max6690_probe,
|
||||
.remove = wf_max6690_remove,
|
||||
|
@ -341,9 +341,16 @@ static const struct i2c_device_id wf_sat_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, wf_sat_id);
|
||||
|
||||
static const struct of_device_id wf_sat_of_id[] = {
|
||||
{ .compatible = "smu-sat", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wf_sat_of_id);
|
||||
|
||||
static struct i2c_driver wf_sat_driver = {
|
||||
.driver = {
|
||||
.name = "wf_smu_sat",
|
||||
.of_match_table = wf_sat_of_id,
|
||||
},
|
||||
.probe = wf_sat_probe,
|
||||
.remove = wf_sat_remove,
|
||||
|
@ -712,13 +712,14 @@ static int at24_probe(struct i2c_client *client)
|
||||
* chip is functional.
|
||||
*/
|
||||
err = at24_read(at24, 0, &test_byte, 1);
|
||||
pm_runtime_idle(dev);
|
||||
if (err) {
|
||||
pm_runtime_disable(dev);
|
||||
regulator_disable(at24->vcc_reg);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pm_runtime_idle(dev);
|
||||
|
||||
if (writable)
|
||||
dev_info(dev, "%u byte %s EEPROM, writable, %u bytes/write\n",
|
||||
byte_len, client->name, at24->write_max);
|
||||
|
@ -1,10 +1,12 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* iTCO Vendor Specific Support hooks */
|
||||
#ifdef CONFIG_ITCO_VENDOR_SUPPORT
|
||||
extern int iTCO_vendorsupport;
|
||||
extern void iTCO_vendor_pre_start(struct resource *, unsigned int);
|
||||
extern void iTCO_vendor_pre_stop(struct resource *);
|
||||
extern int iTCO_vendor_check_noreboot_on(void);
|
||||
#else
|
||||
#define iTCO_vendorsupport 0
|
||||
#define iTCO_vendor_pre_start(acpibase, heartbeat) {}
|
||||
#define iTCO_vendor_pre_stop(acpibase) {}
|
||||
#define iTCO_vendor_check_noreboot_on() 1
|
||||
|
@ -39,8 +39,10 @@
|
||||
/* Broken BIOS */
|
||||
#define BROKEN_BIOS 911
|
||||
|
||||
static int vendorsupport;
|
||||
module_param(vendorsupport, int, 0);
|
||||
int iTCO_vendorsupport;
|
||||
EXPORT_SYMBOL(iTCO_vendorsupport);
|
||||
|
||||
module_param_named(vendorsupport, iTCO_vendorsupport, int, 0);
|
||||
MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default="
|
||||
"0 (none), 1=SuperMicro Pent3, 911=Broken SMI BIOS");
|
||||
|
||||
@ -152,7 +154,7 @@ static void broken_bios_stop(struct resource *smires)
|
||||
void iTCO_vendor_pre_start(struct resource *smires,
|
||||
unsigned int heartbeat)
|
||||
{
|
||||
switch (vendorsupport) {
|
||||
switch (iTCO_vendorsupport) {
|
||||
case SUPERMICRO_OLD_BOARD:
|
||||
supermicro_old_pre_start(smires);
|
||||
break;
|
||||
@ -165,7 +167,7 @@ EXPORT_SYMBOL(iTCO_vendor_pre_start);
|
||||
|
||||
void iTCO_vendor_pre_stop(struct resource *smires)
|
||||
{
|
||||
switch (vendorsupport) {
|
||||
switch (iTCO_vendorsupport) {
|
||||
case SUPERMICRO_OLD_BOARD:
|
||||
supermicro_old_pre_stop(smires);
|
||||
break;
|
||||
@ -178,7 +180,7 @@ EXPORT_SYMBOL(iTCO_vendor_pre_stop);
|
||||
|
||||
int iTCO_vendor_check_noreboot_on(void)
|
||||
{
|
||||
switch (vendorsupport) {
|
||||
switch (iTCO_vendorsupport) {
|
||||
case SUPERMICRO_OLD_BOARD:
|
||||
return 0;
|
||||
default:
|
||||
@ -189,13 +191,13 @@ EXPORT_SYMBOL(iTCO_vendor_check_noreboot_on);
|
||||
|
||||
static int __init iTCO_vendor_init_module(void)
|
||||
{
|
||||
if (vendorsupport == SUPERMICRO_NEW_BOARD) {
|
||||
if (iTCO_vendorsupport == SUPERMICRO_NEW_BOARD) {
|
||||
pr_warn("Option vendorsupport=%d is no longer supported, "
|
||||
"please use the w83627hf_wdt driver instead\n",
|
||||
SUPERMICRO_NEW_BOARD);
|
||||
return -EINVAL;
|
||||
}
|
||||
pr_info("vendor-support=%d\n", vendorsupport);
|
||||
pr_info("vendor-support=%d\n", iTCO_vendorsupport);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -459,13 +459,25 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
|
||||
if (!p->tco_res)
|
||||
return -ENODEV;
|
||||
|
||||
p->smi_res = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_IO_SMI);
|
||||
if (!p->smi_res)
|
||||
return -ENODEV;
|
||||
|
||||
p->iTCO_version = pdata->version;
|
||||
p->pci_dev = to_pci_dev(dev->parent);
|
||||
|
||||
p->smi_res = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_IO_SMI);
|
||||
if (p->smi_res) {
|
||||
/* The TCO logic uses the TCO_EN bit in the SMI_EN register */
|
||||
if (!devm_request_region(dev, p->smi_res->start,
|
||||
resource_size(p->smi_res),
|
||||
pdev->name)) {
|
||||
pr_err("I/O address 0x%04llx already in use, device disabled\n",
|
||||
(u64)SMI_EN(p));
|
||||
return -EBUSY;
|
||||
}
|
||||
} else if (iTCO_vendorsupport ||
|
||||
turn_SMI_watchdog_clear_off >= p->iTCO_version) {
|
||||
pr_err("SMI I/O resource is missing\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
iTCO_wdt_no_reboot_bit_setup(p, pdata);
|
||||
|
||||
/*
|
||||
@ -492,14 +504,6 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
|
||||
/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
|
||||
p->update_no_reboot_bit(p->no_reboot_priv, true);
|
||||
|
||||
/* The TCO logic uses the TCO_EN bit in the SMI_EN register */
|
||||
if (!devm_request_region(dev, p->smi_res->start,
|
||||
resource_size(p->smi_res),
|
||||
pdev->name)) {
|
||||
pr_err("I/O address 0x%04llx already in use, device disabled\n",
|
||||
(u64)SMI_EN(p));
|
||||
return -EBUSY;
|
||||
}
|
||||
if (turn_SMI_watchdog_clear_off >= p->iTCO_version) {
|
||||
/*
|
||||
* Bit 13: TCO_EN -> 0
|
||||
|
Loading…
Reference in New Issue
Block a user