diff options
Diffstat (limited to 'drivers/platform')
| -rw-r--r-- | drivers/platform/goldfish/Kconfig | 5 | ||||
| -rw-r--r-- | drivers/platform/goldfish/Makefile | 1 | ||||
| -rw-r--r-- | drivers/platform/goldfish/goldfish_pipe.c | 3 | ||||
| -rw-r--r-- | drivers/platform/goldfish/pdev_bus.c | 232 | ||||
| -rw-r--r-- | drivers/platform/mips/cpu_hwmon.c | 3 | ||||
| -rw-r--r-- | drivers/platform/x86/Kconfig | 11 | ||||
| -rw-r--r-- | drivers/platform/x86/Makefile | 1 | ||||
| -rw-r--r-- | drivers/platform/x86/asus-wmi.c | 12 | ||||
| -rw-r--r-- | drivers/platform/x86/dell-laptop.c | 2 | ||||
| -rw-r--r-- | drivers/platform/x86/eeepc-laptop.c | 12 | ||||
| -rw-r--r-- | drivers/platform/x86/i2c-multi-instantiate.c | 132 | ||||
| -rw-r--r-- | drivers/platform/x86/intel_bxtwc_tmu.c | 1 | ||||
| -rw-r--r-- | drivers/platform/x86/intel_punit_ipc.c | 1 |
13 files changed, 159 insertions, 257 deletions
diff --git a/drivers/platform/goldfish/Kconfig b/drivers/platform/goldfish/Kconfig index fefbb8370da0..479031aa4f88 100644 --- a/drivers/platform/goldfish/Kconfig +++ b/drivers/platform/goldfish/Kconfig @@ -10,11 +10,6 @@ menuconfig GOLDFISH if GOLDFISH -config GOLDFISH_BUS - bool "Goldfish platform bus" - ---help--- - This is a virtual bus to host Goldfish Android Virtual Devices. - config GOLDFISH_PIPE tristate "Goldfish virtual device for QEMU pipes" ---help--- diff --git a/drivers/platform/goldfish/Makefile b/drivers/platform/goldfish/Makefile index d3487125838c..e0c202df9674 100644 --- a/drivers/platform/goldfish/Makefile +++ b/drivers/platform/goldfish/Makefile @@ -1,5 +1,4 @@ # # Makefile for Goldfish platform specific drivers # -obj-$(CONFIG_GOLDFISH_BUS) += pdev_bus.o obj-$(CONFIG_GOLDFISH_PIPE) += goldfish_pipe.o diff --git a/drivers/platform/goldfish/goldfish_pipe.c b/drivers/platform/goldfish/goldfish_pipe.c index 3e32a4c14d5f..2da567540c2d 100644 --- a/drivers/platform/goldfish/goldfish_pipe.c +++ b/drivers/platform/goldfish/goldfish_pipe.c @@ -48,6 +48,7 @@ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/spinlock.h> @@ -645,7 +646,7 @@ static void goldfish_interrupt_task(unsigned long unused) wake_up_interruptible(&pipe->wake_queue); } } -DECLARE_TASKLET(goldfish_interrupt_tasklet, goldfish_interrupt_task, 0); +static DECLARE_TASKLET(goldfish_interrupt_tasklet, goldfish_interrupt_task, 0); /* * The general idea of the interrupt handling: diff --git a/drivers/platform/goldfish/pdev_bus.c b/drivers/platform/goldfish/pdev_bus.c deleted file mode 100644 index dd9ea463c2a4..000000000000 --- a/drivers/platform/goldfish/pdev_bus.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2007 Google, Inc. - * Copyright (C) 2011 Intel, Inc. - * Copyright (C) 2013 Intel, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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 <linux/kernel.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/io.h> - -#define PDEV_BUS_OP_DONE (0x00) -#define PDEV_BUS_OP_REMOVE_DEV (0x04) -#define PDEV_BUS_OP_ADD_DEV (0x08) - -#define PDEV_BUS_OP_INIT (0x00) - -#define PDEV_BUS_OP (0x00) -#define PDEV_BUS_GET_NAME (0x04) -#define PDEV_BUS_NAME_LEN (0x08) -#define PDEV_BUS_ID (0x0c) -#define PDEV_BUS_IO_BASE (0x10) -#define PDEV_BUS_IO_SIZE (0x14) -#define PDEV_BUS_IRQ (0x18) -#define PDEV_BUS_IRQ_COUNT (0x1c) -#define PDEV_BUS_GET_NAME_HIGH (0x20) - -struct pdev_bus_dev { - struct list_head list; - struct platform_device pdev; - struct resource resources[0]; -}; - -static void goldfish_pdev_worker(struct work_struct *work); - -static void __iomem *pdev_bus_base; -static unsigned long pdev_bus_addr; -static unsigned long pdev_bus_len; -static u32 pdev_bus_irq; -static LIST_HEAD(pdev_bus_new_devices); -static LIST_HEAD(pdev_bus_registered_devices); -static LIST_HEAD(pdev_bus_removed_devices); -static DECLARE_WORK(pdev_bus_worker, goldfish_pdev_worker); - - -static void goldfish_pdev_worker(struct work_struct *work) -{ - int ret; - struct pdev_bus_dev *pos, *n; - - list_for_each_entry_safe(pos, n, &pdev_bus_removed_devices, list) { - list_del(&pos->list); - platform_device_unregister(&pos->pdev); - kfree(pos); - } - list_for_each_entry_safe(pos, n, &pdev_bus_new_devices, list) { - list_del(&pos->list); - ret = platform_device_register(&pos->pdev); - if (ret) - pr_err("goldfish_pdev_worker failed to register device, %s\n", - pos->pdev.name); - list_add_tail(&pos->list, &pdev_bus_registered_devices); - } -} - -static void goldfish_pdev_remove(void) -{ - struct pdev_bus_dev *pos, *n; - u32 base; - - base = readl(pdev_bus_base + PDEV_BUS_IO_BASE); - - list_for_each_entry_safe(pos, n, &pdev_bus_new_devices, list) { - if (pos->resources[0].start == base) { - list_del(&pos->list); - kfree(pos); - return; - } - } - list_for_each_entry_safe(pos, n, &pdev_bus_registered_devices, list) { - if (pos->resources[0].start == base) { - list_del(&pos->list); - list_add_tail(&pos->list, &pdev_bus_removed_devices); - schedule_work(&pdev_bus_worker); - return; - } - }; - pr_err("goldfish_pdev_remove could not find device at %x\n", base); -} - -static int goldfish_new_pdev(void) -{ - struct pdev_bus_dev *dev; - u32 name_len; - u32 irq = -1, irq_count; - int resource_count = 2; - u32 base; - char *name; - - base = readl(pdev_bus_base + PDEV_BUS_IO_BASE); - - irq_count = readl(pdev_bus_base + PDEV_BUS_IRQ_COUNT); - name_len = readl(pdev_bus_base + PDEV_BUS_NAME_LEN); - if (irq_count) - resource_count++; - - dev = kzalloc(sizeof(*dev) + - sizeof(struct resource) * resource_count + - name_len + 1 + sizeof(*dev->pdev.dev.dma_mask), GFP_ATOMIC); - if (dev == NULL) - return -ENOMEM; - - dev->pdev.num_resources = resource_count; - dev->pdev.resource = (struct resource *)(dev + 1); - dev->pdev.name = name = (char *)(dev->pdev.resource + resource_count); - dev->pdev.dev.coherent_dma_mask = ~0; - dev->pdev.dev.dma_mask = (void *)(dev->pdev.name + name_len + 1); - *dev->pdev.dev.dma_mask = ~0; - -#ifdef CONFIG_64BIT - writel((u32)((u64)name>>32), pdev_bus_base + PDEV_BUS_GET_NAME_HIGH); -#endif - writel((u32)(unsigned long)name, pdev_bus_base + PDEV_BUS_GET_NAME); - name[name_len] = '\0'; - dev->pdev.id = readl(pdev_bus_base + PDEV_BUS_ID); - dev->pdev.resource[0].start = base; - dev->pdev.resource[0].end = base + - readl(pdev_bus_base + PDEV_BUS_IO_SIZE) - 1; - dev->pdev.resource[0].flags = IORESOURCE_MEM; - if (irq_count) { - irq = readl(pdev_bus_base + PDEV_BUS_IRQ); - dev->pdev.resource[1].start = irq; - dev->pdev.resource[1].end = irq + irq_count - 1; - dev->pdev.resource[1].flags = IORESOURCE_IRQ; - } - - pr_debug("goldfish_new_pdev %s at %x irq %d\n", name, base, irq); - list_add_tail(&dev->list, &pdev_bus_new_devices); - schedule_work(&pdev_bus_worker); - - return 0; -} - -static irqreturn_t goldfish_pdev_bus_interrupt(int irq, void *dev_id) -{ - irqreturn_t ret = IRQ_NONE; - - while (1) { - u32 op = readl(pdev_bus_base + PDEV_BUS_OP); - - switch (op) { - case PDEV_BUS_OP_REMOVE_DEV: - goldfish_pdev_remove(); - ret = IRQ_HANDLED; - break; - - case PDEV_BUS_OP_ADD_DEV: - goldfish_new_pdev(); - ret = IRQ_HANDLED; - break; - - case PDEV_BUS_OP_DONE: - default: - return ret; - } - } -} - -static int goldfish_pdev_bus_probe(struct platform_device *pdev) -{ - int ret; - struct resource *r; - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (r == NULL) - return -EINVAL; - - pdev_bus_addr = r->start; - pdev_bus_len = resource_size(r); - - pdev_bus_base = ioremap(pdev_bus_addr, pdev_bus_len); - if (pdev_bus_base == NULL) { - ret = -ENOMEM; - dev_err(&pdev->dev, "unable to map Goldfish MMIO.\n"); - goto free_resources; - } - - r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (r == NULL) { - ret = -ENOENT; - goto free_map; - } - - pdev_bus_irq = r->start; - - ret = request_irq(pdev_bus_irq, goldfish_pdev_bus_interrupt, - IRQF_SHARED, "goldfish_pdev_bus", pdev); - if (ret) { - dev_err(&pdev->dev, "unable to request Goldfish IRQ\n"); - goto free_map; - } - - writel(PDEV_BUS_OP_INIT, pdev_bus_base + PDEV_BUS_OP); - return 0; - -free_map: - iounmap(pdev_bus_base); -free_resources: - release_mem_region(pdev_bus_addr, pdev_bus_len); - return ret; -} - -static struct platform_driver goldfish_pdev_bus_driver = { - .probe = goldfish_pdev_bus_probe, - .driver = { - .name = "goldfish_pdev_bus" - } -}; -builtin_platform_driver(goldfish_pdev_bus_driver); diff --git a/drivers/platform/mips/cpu_hwmon.c b/drivers/platform/mips/cpu_hwmon.c index 322de58eebaf..f66521c7f846 100644 --- a/drivers/platform/mips/cpu_hwmon.c +++ b/drivers/platform/mips/cpu_hwmon.c @@ -30,7 +30,8 @@ int loongson3_cpu_temp(int cpu) case PRID_REV_LOONGSON3B_R2: reg = ((reg >> 8) & 0xff) - 100; break; - case PRID_REV_LOONGSON3A_R3: + case PRID_REV_LOONGSON3A_R3_0: + case PRID_REV_LOONGSON3A_R3_1: reg = (reg & 0xffff)*731/0x4000 - 273; break; } diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index ac4d48830415..107d336453b2 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -1218,6 +1218,17 @@ config INTEL_CHTDC_TI_PWRBTN To compile this driver as a module, choose M here: the module will be called intel_chtdc_ti_pwrbtn. +config I2C_MULTI_INSTANTIATE + tristate "I2C multi instantiate pseudo device driver" + depends on I2C && ACPI + help + Some ACPI-based systems list multiple i2c-devices in a single ACPI + firmware-node. This driver will instantiate separate i2c-clients + for each device in the firmware-node. + + To compile this driver as a module, choose M here: the module + will be called i2c-multi-instantiate. + endif # X86_PLATFORM_DEVICES config PMC_ATOM diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 2ba6cb795338..50dc8f280914 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -91,3 +91,4 @@ obj-$(CONFIG_PMC_ATOM) += pmc_atom.o obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o obj-$(CONFIG_INTEL_CHTDC_TI_PWRBTN) += intel_chtdc_ti_pwrbtn.o +obj-$(CONFIG_I2C_MULTI_INSTANTIATE) += i2c-multi-instantiate.o diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 3d523ca64694..d67f32a29bb4 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -858,12 +858,6 @@ static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot, return 0; } -static void asus_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot) -{ - kfree(hotplug_slot->info); - kfree(hotplug_slot); -} - static struct hotplug_slot_ops asus_hotplug_slot_ops = { .owner = THIS_MODULE, .get_adapter_status = asus_get_adapter_status, @@ -905,7 +899,6 @@ static int asus_setup_pci_hotplug(struct asus_wmi *asus) goto error_info; asus->hotplug_slot->private = asus; - asus->hotplug_slot->release = &asus_cleanup_pci_hotplug; asus->hotplug_slot->ops = &asus_hotplug_slot_ops; asus_get_adapter_status(asus->hotplug_slot, &asus->hotplug_slot->info->adapter_status); @@ -1051,8 +1044,11 @@ static void asus_wmi_rfkill_exit(struct asus_wmi *asus) * asus_unregister_rfkill_notifier() */ asus_rfkill_hotplug(asus); - if (asus->hotplug_slot) + if (asus->hotplug_slot) { pci_hp_deregister(asus->hotplug_slot); + kfree(asus->hotplug_slot->info); + kfree(asus->hotplug_slot); + } if (asus->hotplug_workqueue) destroy_workqueue(asus->hotplug_workqueue); diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index f1fa8612db40..06978c14c83b 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -2185,7 +2185,7 @@ static int __init dell_init(void) dell_fill_request(&buffer, token->location, 0, 0, 0); ret = dell_send_request(&buffer, CLASS_TOKEN_READ, SELECT_TOKEN_AC); - if (ret) + if (ret == 0) max_intensity = buffer.output[3]; } diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 4c38904a8a32..a4bbf6ecd1f0 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -726,12 +726,6 @@ static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, return 0; } -static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot) -{ - kfree(hotplug_slot->info); - kfree(hotplug_slot); -} - static struct hotplug_slot_ops eeepc_hotplug_slot_ops = { .owner = THIS_MODULE, .get_adapter_status = eeepc_get_adapter_status, @@ -758,7 +752,6 @@ static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc) goto error_info; eeepc->hotplug_slot->private = eeepc; - eeepc->hotplug_slot->release = &eeepc_cleanup_pci_hotplug; eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops; eeepc_get_adapter_status(eeepc->hotplug_slot, &eeepc->hotplug_slot->info->adapter_status); @@ -837,8 +830,11 @@ static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc) eeepc->wlan_rfkill = NULL; } - if (eeepc->hotplug_slot) + if (eeepc->hotplug_slot) { pci_hp_deregister(eeepc->hotplug_slot); + kfree(eeepc->hotplug_slot->info); + kfree(eeepc->hotplug_slot); + } if (eeepc->bluetooth_rfkill) { rfkill_unregister(eeepc->bluetooth_rfkill); diff --git a/drivers/platform/x86/i2c-multi-instantiate.c b/drivers/platform/x86/i2c-multi-instantiate.c new file mode 100644 index 000000000000..5456581b473c --- /dev/null +++ b/drivers/platform/x86/i2c-multi-instantiate.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * I2C multi-instantiate driver, pseudo driver to instantiate multiple + * i2c-clients from a single fwnode. + * + * Copyright 2018 Hans de Goede <[email protected]> + */ + +#include <linux/acpi.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> + +struct i2c_inst_data { + const char *type; + int gpio_irq_idx; +}; + +struct i2c_multi_inst_data { + int num_clients; + struct i2c_client *clients[0]; +}; + +static int i2c_multi_inst_probe(struct platform_device *pdev) +{ + struct i2c_multi_inst_data *multi; + const struct acpi_device_id *match; + const struct i2c_inst_data *inst_data; + struct i2c_board_info board_info = {}; + struct device *dev = &pdev->dev; + struct acpi_device *adev; + char name[32]; + int i, ret; + + match = acpi_match_device(dev->driver->acpi_match_table, dev); + if (!match) { + dev_err(dev, "Error ACPI match data is missing\n"); + return -ENODEV; + } + inst_data = (const struct i2c_inst_data *)match->driver_data; + + adev = ACPI_COMPANION(dev); + + /* Count number of clients to instantiate */ + for (i = 0; inst_data[i].type; i++) {} + + multi = devm_kmalloc(dev, + offsetof(struct i2c_multi_inst_data, clients[i]), + GFP_KERNEL); + if (!multi) + return -ENOMEM; + + multi->num_clients = i; + + for (i = 0; i < multi->num_clients; i++) { + memset(&board_info, 0, sizeof(board_info)); + strlcpy(board_info.type, inst_data[i].type, I2C_NAME_SIZE); + snprintf(name, sizeof(name), "%s-%s", match->id, + inst_data[i].type); + board_info.dev_name = name; + board_info.irq = 0; + if (inst_data[i].gpio_irq_idx != -1) { + ret = acpi_dev_gpio_irq_get(adev, + inst_data[i].gpio_irq_idx); + if (ret < 0) { + dev_err(dev, "Error requesting irq at index %d: %d\n", + inst_data[i].gpio_irq_idx, ret); + goto error; + } + board_info.irq = ret; + } + multi->clients[i] = i2c_acpi_new_device(dev, i, &board_info); + if (!multi->clients[i]) { + dev_err(dev, "Error creating i2c-client, idx %d\n", i); + ret = -ENODEV; + goto error; + } + } + + platform_set_drvdata(pdev, multi); + return 0; + +error: + while (--i >= 0) + i2c_unregister_device(multi->clients[i]); + + return ret; +} + +static int i2c_multi_inst_remove(struct platform_device *pdev) +{ + struct i2c_multi_inst_data *multi = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < multi->num_clients; i++) + i2c_unregister_device(multi->clients[i]); + + return 0; +} + +static const struct i2c_inst_data bsg1160_data[] = { + { "bmc150_accel", 0 }, + { "bmc150_magn", -1 }, + { "bmg160", -1 }, + {} +}; + +/* + * Note new device-ids must also be added to i2c_multi_instantiate_ids in + * drivers/acpi/scan.c: acpi_device_enumeration_by_parent(). + */ +static const struct acpi_device_id i2c_multi_inst_acpi_ids[] = { + { "BSG1160", (unsigned long)bsg1160_data }, + { } +}; +MODULE_DEVICE_TABLE(acpi, i2c_multi_inst_acpi_ids); + +static struct platform_driver i2c_multi_inst_driver = { + .driver = { + .name = "I2C multi instantiate pseudo device driver", + .acpi_match_table = ACPI_PTR(i2c_multi_inst_acpi_ids), + }, + .probe = i2c_multi_inst_probe, + .remove = i2c_multi_inst_remove, +}; +module_platform_driver(i2c_multi_inst_driver); + +MODULE_DESCRIPTION("I2C multi instantiate pseudo device driver"); +MODULE_AUTHOR("Hans de Goede <[email protected]>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/intel_bxtwc_tmu.c b/drivers/platform/x86/intel_bxtwc_tmu.c index ea865d4ca220..227943a20212 100644 --- a/drivers/platform/x86/intel_bxtwc_tmu.c +++ b/drivers/platform/x86/intel_bxtwc_tmu.c @@ -19,6 +19,7 @@ */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/interrupt.h> #include <linux/platform_device.h> #include <linux/mfd/intel_soc_pmic.h> diff --git a/drivers/platform/x86/intel_punit_ipc.c b/drivers/platform/x86/intel_punit_ipc.c index b5b890127479..f1afc0ebbc68 100644 --- a/drivers/platform/x86/intel_punit_ipc.c +++ b/drivers/platform/x86/intel_punit_ipc.c @@ -12,6 +12,7 @@ */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/acpi.h> #include <linux/delay.h> #include <linux/bitops.h> |