From 6ad95513d60096b569e4e4bd721420f03b57e4d4 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 11 Mar 2010 12:20:06 -0700 Subject: ACPI: pci_root: save downstream bus range Previously, we only saved the root bus number, i.e., the beginning of the downstream bus range. We now support IORESOURCE_BUS resources, so this patch uses that to keep track of both the beginning and the end of the downstream bus range. It's important to know both the beginning and the end for supporting _CBA (see PCI Firmware spec, rev 3.0, sec 4.1.3) and so we know the limits for any possible PCI bus renumbering (we can't renumber downstream buses to be outside the bus number range claimed by the host bridge). It's clear from the spec that the bus range is supposed to be in _CRS, but if we don't find it there, we'll assume [_BBN - 0xFF] or [0 - 0xFF]. Signed-off-by: Bjorn Helgaas Reviewed-by: Kenji Kaneshige Signed-off-by: Len Brown --- include/acpi/acpi_bus.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 7bf83ddf82e0..baacd98e7cc6 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -373,7 +373,7 @@ struct acpi_pci_root { struct acpi_pci_id id; struct pci_bus *bus; u16 segment; - u8 bus_nr; + struct resource secondary; /* downstream bus range */ u32 osc_support_set; /* _OSC state of support bits */ u32 osc_control_set; /* _OSC state of control bits */ -- cgit v1.2.3-71-gd317 From 57283776b2b821ba4d592f61cad04d0293412740 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 11 Mar 2010 12:20:11 -0700 Subject: ACPI: pci_root: pass acpi_pci_root to arch-specific scan The acpi_pci_root structure contains all the individual items (acpi_device, domain, bus number) we pass to pci_acpi_scan_root(), so just pass the single acpi_pci_root pointer directly. This will make it easier to add _CBA support later. For _CBA, we need the entire downstream bus range, not just the base bus number. We have that in the acpi_pci_root structure, so passing the pointer makes it available to the arch-specific code. Signed-off-by: Bjorn Helgaas Reviewed-by: Kenji Kaneshige Signed-off-by: Len Brown --- arch/ia64/pci/pci.c | 5 ++++- arch/x86/pci/acpi.c | 5 ++++- drivers/acpi/pci_root.c | 2 +- include/acpi/acpi_drivers.h | 3 +-- 4 files changed, 10 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 64aff520b899..aa2533ae7e9e 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -335,8 +335,11 @@ pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl) } struct pci_bus * __devinit -pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) +pci_acpi_scan_root(struct acpi_pci_root *root) { + struct acpi_device *device = root->device; + int domain = root->segment; + int bus = root->secondary.start; struct pci_controller *controller; unsigned int windows = 0; struct pci_bus *pbus; diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index e31160216efb..0b7882dbe784 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -229,8 +229,11 @@ res_alloc_fail: return; } -struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum) +struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) { + struct acpi_device *device = root->device; + int domain = root->segment; + int busnum = root->secondary.start; struct pci_bus *bus; struct pci_sysdata *sd; int node; diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index bf476fea97ab..680450c905b3 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -498,7 +498,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) * PCI namespace does not get created until this call is made (and * thus the root bridge's pci_dev does not exist). */ - root->bus = pci_acpi_scan_root(device, segment, root->secondary.start); + root->bus = pci_acpi_scan_root(root); if (!root->bus) { printk(KERN_ERR PREFIX "Bus %04x:%02x not present in PCI namespace\n", diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 4f7b44866b76..23d78b4d088b 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -104,8 +104,7 @@ int acpi_pci_bind_root(struct acpi_device *device); /* Arch-defined function to add a bus to the system */ -struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain, - int bus); +struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root); void pci_acpi_crs_quirks(void); /* -------------------------------------------------------------------------- -- cgit v1.2.3-71-gd317 From e3e8d1c93f9e6b766424b05f23f2416f22a0329d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 28 Feb 2010 12:47:49 +0100 Subject: Driver for Zipit Z2 battery chip This patch adds driver for Zipit Z2 battery chip called AER915. No details are known about the chip. The chip is available through I2C bus at address 0x55 and it's register 0x02 contains battery voltage. Signed-off-by: Marek Vasut Signed-off-by: Anton Vorontsov --- drivers/power/Kconfig | 6 + drivers/power/Makefile | 1 + drivers/power/z2_battery.c | 328 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/z2_battery.h | 17 +++ 4 files changed, 352 insertions(+) create mode 100644 drivers/power/z2_battery.c create mode 100644 include/linux/z2_battery.h (limited to 'include') diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index faaa9b4d0d07..22f2fa912127 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -125,6 +125,12 @@ config BATTERY_MAX17040 in handheld and portable equipment. The MAX17040 is configured to operate with a single lithium cell +config BATTERY_Z2 + tristate "Z2 battery driver" + depends on I2C && MACH_ZIPIT2 + help + Say Y to include support for the battery on the Zipit Z2. + config CHARGER_PCF50633 tristate "NXP PCF50633 MBC" depends on MFD_PCF50633 diff --git a/drivers/power/Makefile b/drivers/power/Makefile index a2ba7c85c97a..a82f292e5c94 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -31,4 +31,5 @@ obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o +obj-$(CONFIG_BATTERY_Z2) += z2_battery.o obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o diff --git a/drivers/power/z2_battery.c b/drivers/power/z2_battery.c new file mode 100644 index 000000000000..9cca465436e3 --- /dev/null +++ b/drivers/power/z2_battery.c @@ -0,0 +1,328 @@ +/* + * Battery measurement code for Zipit Z2 + * + * Copyright (C) 2009 Peter Edwards + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define Z2_DEFAULT_NAME "Z2" + +struct z2_charger { + struct z2_battery_info *info; + int bat_status; + struct i2c_client *client; + struct power_supply batt_ps; + struct mutex work_lock; + struct work_struct bat_work; +}; + +static unsigned long z2_read_bat(struct z2_charger *charger) +{ + int data; + data = i2c_smbus_read_byte_data(charger->client, + charger->info->batt_I2C_reg); + if (data < 0) + return 0; + + return data * charger->info->batt_mult / charger->info->batt_div; +} + +static int z2_batt_get_property(struct power_supply *batt_ps, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct z2_charger *charger = container_of(batt_ps, struct z2_charger, + batt_ps); + struct z2_battery_info *info = charger->info; + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + val->intval = charger->bat_status; + break; + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = info->batt_tech; + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + if (info->batt_I2C_reg >= 0) + val->intval = z2_read_bat(charger); + else + return -EINVAL; + break; + case POWER_SUPPLY_PROP_VOLTAGE_MAX: + if (info->max_voltage >= 0) + val->intval = info->max_voltage; + else + return -EINVAL; + break; + case POWER_SUPPLY_PROP_VOLTAGE_MIN: + if (info->min_voltage >= 0) + val->intval = info->min_voltage; + else + return -EINVAL; + break; + case POWER_SUPPLY_PROP_PRESENT: + val->intval = 1; + break; + default: + return -EINVAL; + } + + return 0; +} + +static void z2_batt_ext_power_changed(struct power_supply *batt_ps) +{ + struct z2_charger *charger = container_of(batt_ps, struct z2_charger, + batt_ps); + schedule_work(&charger->bat_work); +} + +static void z2_batt_update(struct z2_charger *charger) +{ + int old_status = charger->bat_status; + struct z2_battery_info *info; + + info = charger->info; + + mutex_lock(&charger->work_lock); + + charger->bat_status = (info->charge_gpio >= 0) ? + (gpio_get_value(info->charge_gpio) ? + POWER_SUPPLY_STATUS_CHARGING : + POWER_SUPPLY_STATUS_DISCHARGING) : + POWER_SUPPLY_STATUS_UNKNOWN; + + if (old_status != charger->bat_status) { + pr_debug("%s: %i -> %i\n", charger->batt_ps.name, old_status, + charger->bat_status); + power_supply_changed(&charger->batt_ps); + } + + mutex_unlock(&charger->work_lock); +} + +static void z2_batt_work(struct work_struct *work) +{ + struct z2_charger *charger; + charger = container_of(work, struct z2_charger, bat_work); + z2_batt_update(charger); +} + +static irqreturn_t z2_charge_switch_irq(int irq, void *devid) +{ + struct z2_charger *charger = devid; + schedule_work(&charger->bat_work); + return IRQ_HANDLED; +} + +static int z2_batt_ps_init(struct z2_charger *charger, int props) +{ + int i = 0; + enum power_supply_property *prop; + struct z2_battery_info *info = charger->info; + + if (info->batt_tech >= 0) + props++; /* POWER_SUPPLY_PROP_TECHNOLOGY */ + if (info->batt_I2C_reg >= 0) + props++; /* POWER_SUPPLY_PROP_VOLTAGE_NOW */ + if (info->max_voltage >= 0) + props++; /* POWER_SUPPLY_PROP_VOLTAGE_MAX */ + if (info->min_voltage >= 0) + props++; /* POWER_SUPPLY_PROP_VOLTAGE_MIN */ + + prop = kzalloc(props * sizeof(*prop), GFP_KERNEL); + if (!prop) + return -ENOMEM; + + prop[i++] = POWER_SUPPLY_PROP_PRESENT; + if (info->charge_gpio >= 0) + prop[i++] = POWER_SUPPLY_PROP_STATUS; + if (info->batt_tech >= 0) + prop[i++] = POWER_SUPPLY_PROP_TECHNOLOGY; + if (info->batt_I2C_reg >= 0) + prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_NOW; + if (info->max_voltage >= 0) + prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_MAX; + if (info->min_voltage >= 0) + prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_MIN; + + if (!info->batt_name) { + dev_info(&charger->client->dev, + "Please consider setting proper battery " + "name in platform definition file, falling " + "back to name \" Z2_DEFAULT_NAME \"\n"); + charger->batt_ps.name = Z2_DEFAULT_NAME; + } else + charger->batt_ps.name = info->batt_name; + + charger->batt_ps.properties = prop; + charger->batt_ps.num_properties = props; + charger->batt_ps.type = POWER_SUPPLY_TYPE_BATTERY; + charger->batt_ps.get_property = z2_batt_get_property; + charger->batt_ps.external_power_changed = z2_batt_ext_power_changed; + charger->batt_ps.use_for_apm = 1; + + return 0; +} + +static int __devinit z2_batt_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0; + int props = 1; /* POWER_SUPPLY_PROP_PRESENT */ + struct z2_charger *charger; + struct z2_battery_info *info = client->dev.platform_data; + + if (info == NULL) { + dev_err(&client->dev, + "Please set platform device platform_data" + " to a valid z2_battery_info pointer!\n"); + return -EINVAL; + } + + charger = kzalloc(sizeof(*charger), GFP_KERNEL); + if (charger == NULL) + return -ENOMEM; + + charger->bat_status = POWER_SUPPLY_STATUS_UNKNOWN; + charger->info = info; + charger->client = client; + i2c_set_clientdata(client, charger); + + mutex_init(&charger->work_lock); + + if (info->charge_gpio >= 0 && gpio_is_valid(info->charge_gpio)) { + ret = gpio_request(info->charge_gpio, "BATT CHRG"); + if (ret) + goto err; + + ret = gpio_direction_input(info->charge_gpio); + if (ret) + goto err2; + + set_irq_type(gpio_to_irq(info->charge_gpio), + IRQ_TYPE_EDGE_BOTH); + ret = request_irq(gpio_to_irq(info->charge_gpio), + z2_charge_switch_irq, IRQF_DISABLED, + "AC Detect", charger); + if (ret) + goto err3; + } + + ret = z2_batt_ps_init(charger, props); + if (ret) + goto err3; + + INIT_WORK(&charger->bat_work, z2_batt_work); + + ret = power_supply_register(&client->dev, &charger->batt_ps); + if (ret) + goto err4; + + schedule_work(&charger->bat_work); + + return 0; + +err4: + kfree(charger->batt_ps.properties); +err3: + if (info->charge_gpio >= 0 && gpio_is_valid(info->charge_gpio)) + free_irq(gpio_to_irq(info->charge_gpio), charger); +err2: + if (info->charge_gpio >= 0 && gpio_is_valid(info->charge_gpio)) + gpio_free(info->charge_gpio); +err: + kfree(charger); + return ret; +} + +static int __devexit z2_batt_remove(struct i2c_client *client) +{ + struct z2_charger *charger = i2c_get_clientdata(client); + struct z2_battery_info *info = charger->info; + + flush_scheduled_work(); + power_supply_unregister(&charger->batt_ps); + + kfree(charger->batt_ps.properties); + if (info->charge_gpio >= 0 && gpio_is_valid(info->charge_gpio)) { + free_irq(gpio_to_irq(info->charge_gpio), charger); + gpio_free(info->charge_gpio); + } + + kfree(charger); + + return 0; +} + +#ifdef CONFIG_PM +static int z2_batt_suspend(struct i2c_client *client, pm_message_t state) +{ + flush_scheduled_work(); + return 0; +} + +static int z2_batt_resume(struct i2c_client *client) +{ + struct z2_charger *charger = i2c_get_clientdata(client); + + schedule_work(&charger->bat_work); + return 0; +} +#else +#define z2_batt_suspend NULL +#define z2_batt_resume NULL +#endif + +static const struct i2c_device_id z2_batt_id[] = { + { "aer915", 0 }, + { } +}; + +static struct i2c_driver z2_batt_driver = { + .driver = { + .name = "z2-battery", + .owner = THIS_MODULE, + }, + .probe = z2_batt_probe, + .remove = z2_batt_remove, + .suspend = z2_batt_suspend, + .resume = z2_batt_resume, + .id_table = z2_batt_id, +}; + +static int __init z2_batt_init(void) +{ + return i2c_add_driver(&z2_batt_driver); +} + +static void __exit z2_batt_exit(void) +{ + i2c_del_driver(&z2_batt_driver); +} + +module_init(z2_batt_init); +module_exit(z2_batt_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Peter Edwards "); +MODULE_DESCRIPTION("Zipit Z2 battery driver"); diff --git a/include/linux/z2_battery.h b/include/linux/z2_battery.h new file mode 100644 index 000000000000..7b9750404d22 --- /dev/null +++ b/include/linux/z2_battery.h @@ -0,0 +1,17 @@ +#ifndef _LINUX_Z2_BATTERY_H +#define _LINUX_Z2_BATTERY_H + +struct z2_battery_info { + int batt_I2C_bus; + int batt_I2C_addr; + int batt_I2C_reg; + int charge_gpio; + int min_voltage; + int max_voltage; + int batt_div; + int batt_mult; + int batt_tech; + char *batt_name; +}; + +#endif -- cgit v1.2.3-71-gd317 From 3fcb027d7fd749569665d34a79ce2a8e00bc2ed6 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 1 Apr 2010 10:03:25 +0200 Subject: ARM: MXC: mxcmmc: work around a bug in the SDHC busy line handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MX3 SoCs have a silicon bug which corrupts CRC calculation of multi-block transfers when connected SDIO peripheral doesn't drive the BUSY line as required by the specs. One way to prevent this is to only allow 1-bit transfers. Another way is playing tricks with the DMA engine, but this isn't mainline yet. So for now, we live with the performance drawback of 1-bit transfers until a nicer solution is found. This patch introduces a new host controller callback 'init_card' which is for now only called from mmc_sdio_init_card(). Signed-off-by: Daniel Mack Cc: Sascha Hauer Cc: Dan Williams Cc: Volker Ernst Cc: Jiri Kosina Cc: Michał Mirosław Signed-off-by: Sascha Hauer --- drivers/mmc/core/sdio.c | 6 ++++++ drivers/mmc/host/mxcmmc.c | 16 ++++++++++++++++ include/linux/mmc/host.h | 3 +++ 3 files changed, 25 insertions(+) (limited to 'include') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 2dd4cfe7ca17..b9dee28ee7d0 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -295,6 +295,12 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, card->type = MMC_TYPE_SDIO; + /* + * Call the optional HC's init_card function to handle quirks. + */ + if (host->ops->init_card) + host->ops->init_card(host, card); + /* * For native busses: set card RCA and quit open drain mode. */ diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 51e880c8f193..2c53024ee439 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -724,11 +724,27 @@ static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable) spin_unlock_irqrestore(&host->lock, flags); } +static void mxcmci_init_card(struct mmc_host *host, struct mmc_card *card) +{ + /* + * MX3 SoCs have a silicon bug which corrupts CRC calculation of + * multi-block transfers when connected SDIO peripheral doesn't + * drive the BUSY line as required by the specs. + * One way to prevent this is to only allow 1-bit transfers. + */ + + if (cpu_is_mx3() && card->type == MMC_TYPE_SDIO) + host->caps &= ~MMC_CAP_4_BIT_DATA; + else + host->caps |= MMC_CAP_4_BIT_DATA; +} + static const struct mmc_host_ops mxcmci_ops = { .request = mxcmci_request, .set_ios = mxcmci_set_ios, .get_ro = mxcmci_get_ro, .enable_sdio_irq = mxcmci_enable_sdio_irq, + .init_card = mxcmci_init_card, }; static int mxcmci_probe(struct platform_device *pdev) diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 43eaf5ca5848..3196c84cc630 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -108,6 +108,9 @@ struct mmc_host_ops { int (*get_cd)(struct mmc_host *host); void (*enable_sdio_irq)(struct mmc_host *host, int enable); + + /* optional callback for HC quirks */ + void (*init_card)(struct mmc_host *host, struct mmc_card *card); }; struct mmc_card; -- cgit v1.2.3-71-gd317 From 54a4ec469dd6067f0b604bef8ca01a2b1fdb4dcd Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 15 Apr 2010 02:17:25 -0700 Subject: ide: fix comment typo in ide.h Fix typo in the comment to the 'dma_mode' field of the 'struct ide_drive_s' introduced by the commit 3fccaa192b9501e79a57e02e62b6bf420d2b461e (ide: add drive->dma_mode field). Whilt at it, convert spaces to a tab in the declaration of the neighbouring 'dn' field... Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- include/linux/ide.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/ide.h b/include/linux/ide.h index 3239d1c10acb..5acdbe51348a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -516,8 +516,8 @@ struct ide_drive_s { u8 current_speed; /* current transfer rate set */ u8 desired_speed; /* desired transfer rate set */ u8 pio_mode; /* for ->set_pio_mode _only_ */ - u8 dma_mode; /* for ->dma_pio_mode _only_ */ - u8 dn; /* now wide spread use */ + u8 dma_mode; /* for ->set_dma_mode _only_ */ + u8 dn; /* now wide spread use */ u8 acoustic; /* acoustic management */ u8 media; /* disk, cdrom, tape, floppy, ... */ u8 ready_stat; /* min status value for drive ready */ -- cgit v1.2.3-71-gd317 From a3bcbbee83f55cbaec9b2ad748e7300c7feb2192 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 12 Apr 2010 23:33:22 +0200 Subject: pda_power: Add function callbacks for suspend and resume Add function prototypes for power management events so they can be handled and used by platform implementations. Signed-off-by: Daniel Mack Cc: Dmitry Baryshkov Cc: David Woodhouse Signed-off-by: Anton Vorontsov --- drivers/power/pda_power.c | 10 ++++++++++ include/linux/pda_power.h | 2 ++ 2 files changed, 12 insertions(+) (limited to 'include') diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c index a232de6a5703..69f8aa3a6a4b 100644 --- a/drivers/power/pda_power.c +++ b/drivers/power/pda_power.c @@ -404,6 +404,13 @@ static int usb_wakeup_enabled; static int pda_power_suspend(struct platform_device *pdev, pm_message_t state) { + if (pdata->suspend) { + int ret = pdata->suspend(state); + + if (ret) + return ret; + } + if (device_may_wakeup(&pdev->dev)) { if (ac_irq) ac_wakeup_enabled = !enable_irq_wake(ac_irq->start); @@ -423,6 +430,9 @@ static int pda_power_resume(struct platform_device *pdev) disable_irq_wake(ac_irq->start); } + if (pdata->resume) + return pdata->resume(); + return 0; } #else diff --git a/include/linux/pda_power.h b/include/linux/pda_power.h index d4cf7a2ceb3e..c9e4d814ff77 100644 --- a/include/linux/pda_power.h +++ b/include/linux/pda_power.h @@ -24,6 +24,8 @@ struct pda_power_pdata { int (*is_usb_online)(void); void (*set_charge)(int flags); void (*exit)(struct device *dev); + int (*suspend)(pm_message_t state); + int (*resume)(void); char **supplied_to; size_t num_supplicants; -- cgit v1.2.3-71-gd317 From edd5bdaf128e04066caac84fcb21377197ea0d64 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 14 Apr 2010 22:30:18 +0200 Subject: firewire: core: clean up config ROM related defined constants Clemens Ladisch pointed out that - BIB_IMC is not named like the field is called in the standard, - readers of the code may get worried about the magic 0x0c0083c0, - a CSR_NODE_CAPABILITIES key is there in the header but not put to good use. So let's rename BIB_IMC, add a defined constant for Node_Capabilities and a comment which reassures people that somebody thought about it and they don't have to (or if they still do, tell them where they have to look for confirmation), and prune our incomplete and arbitrary set of defined constants of CSR key IDs. And there is a nother magic number, that of Bus_Information_Block.Bus_Name, to be defined and commented. Signed-off-by: Stefan Richter --- drivers/firewire/core-card.c | 11 ++++++----- include/linux/firewire.h | 2 -- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index 5045156c5313..42cf911b73cf 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -63,7 +63,7 @@ static size_t config_rom_length = 1 + 4 + 1 + 1; #define BIB_CRC(v) ((v) << 0) #define BIB_CRC_LENGTH(v) ((v) << 16) #define BIB_INFO_LENGTH(v) ((v) << 24) - +#define BIB_BUS_NAME 0x31333934 /* "1394" */ #define BIB_LINK_SPEED(v) ((v) << 0) #define BIB_GENERATION(v) ((v) << 4) #define BIB_MAX_ROM(v) ((v) << 8) @@ -73,7 +73,8 @@ static size_t config_rom_length = 1 + 4 + 1 + 1; #define BIB_BMC ((1) << 28) #define BIB_ISC ((1) << 29) #define BIB_CMC ((1) << 30) -#define BIB_IMC ((1) << 31) +#define BIB_IRMC ((1) << 31) +#define NODE_CAPABILITIES 0x0c0083c0 /* per IEEE 1394 clause 8.3.2.6.5.2 */ static void generate_config_rom(struct fw_card *card, __be32 *config_rom) { @@ -91,18 +92,18 @@ static void generate_config_rom(struct fw_card *card, __be32 *config_rom) config_rom[0] = cpu_to_be32( BIB_CRC_LENGTH(4) | BIB_INFO_LENGTH(4) | BIB_CRC(0)); - config_rom[1] = cpu_to_be32(0x31333934); + config_rom[1] = cpu_to_be32(BIB_BUS_NAME); config_rom[2] = cpu_to_be32( BIB_LINK_SPEED(card->link_speed) | BIB_GENERATION(card->config_rom_generation++ % 14 + 2) | BIB_MAX_ROM(2) | BIB_MAX_RECEIVE(card->max_receive) | - BIB_BMC | BIB_ISC | BIB_CMC | BIB_IMC); + BIB_BMC | BIB_ISC | BIB_CMC | BIB_IRMC); config_rom[3] = cpu_to_be32(card->guid >> 32); config_rom[4] = cpu_to_be32(card->guid); /* Generate root directory. */ - config_rom[6] = cpu_to_be32(0x0c0083c0); /* node capabilities */ + config_rom[6] = cpu_to_be32(NODE_CAPABILITIES); i = 7; j = 7 + descriptor_count; diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 4bd94bf5e739..a527d73f9966 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -55,13 +55,11 @@ #define CSR_DESCRIPTOR 0x01 #define CSR_VENDOR 0x03 #define CSR_HARDWARE_VERSION 0x04 -#define CSR_NODE_CAPABILITIES 0x0c #define CSR_UNIT 0x11 #define CSR_SPECIFIER_ID 0x12 #define CSR_VERSION 0x13 #define CSR_DEPENDENT_INFO 0x14 #define CSR_MODEL 0x17 -#define CSR_INSTANCE 0x18 #define CSR_DIRECTORY_ID 0x20 struct fw_csr_iterator { -- cgit v1.2.3-71-gd317 From e92a716240258989f19c7345e8b135e6d214431a Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 12 Jan 2010 14:17:03 -0500 Subject: ACPI: Export EDID blocks to the kernel The ACPI spec includes a provision for hardware to provide EDID via the ACPI video extension. In the KMS world it's necessary for a way to obtain this from within the kernel. Add a function that either returns the EDID for the provided ACPI display ID or the first display of the provided type. Also add support for ensuring that devices with legacy IDs are supported. Signed-off-by: Matthew Garrett Acked-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++---- include/acpi/video.h | 16 ++++++++ 2 files changed, 118 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a0c93b321482..4b8bda1154db 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -45,6 +45,7 @@ #include #include #include +#include #define PREFIX "ACPI: " @@ -65,11 +66,6 @@ #define MAX_NAME_LEN 20 -#define ACPI_VIDEO_DISPLAY_CRT 1 -#define ACPI_VIDEO_DISPLAY_TV 2 -#define ACPI_VIDEO_DISPLAY_DVI 3 -#define ACPI_VIDEO_DISPLAY_LCD 4 - #define _COMPONENT ACPI_VIDEO_COMPONENT ACPI_MODULE_NAME("video"); @@ -1747,12 +1743,28 @@ acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id return NULL; } +static int +acpi_video_get_device_type(struct acpi_video_bus *video, + unsigned long device_id) +{ + struct acpi_video_enumerated_device *ids; + int i; + + for (i = 0; i < video->attached_count; i++) { + ids = &video->attached_array[i]; + if ((ids->value.int_val & 0xffff) == device_id) + return ids->value.int_val; + } + + return 0; +} + static int acpi_video_bus_get_one_device(struct acpi_device *device, struct acpi_video_bus *video) { unsigned long long device_id; - int status; + int status, device_type; struct acpi_video_device *data; struct acpi_video_device_attrib* attribute; @@ -1797,8 +1809,25 @@ acpi_video_bus_get_one_device(struct acpi_device *device, } if(attribute->bios_can_detect) data->flags.bios = 1; - } else - data->flags.unknown = 1; + } else { + /* Check for legacy IDs */ + device_type = acpi_video_get_device_type(video, + device_id); + /* Ignore bits 16 and 18-20 */ + switch (device_type & 0xffe2ffff) { + case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR: + data->flags.crt = 1; + break; + case ACPI_VIDEO_DISPLAY_LEGACY_PANEL: + data->flags.lcd = 1; + break; + case ACPI_VIDEO_DISPLAY_LEGACY_TV: + data->flags.tvout = 1; + break; + default: + data->flags.unknown = 1; + } + } acpi_video_device_bind(video, data); acpi_video_device_find_cap(data); @@ -2032,6 +2061,71 @@ out: return result; } +int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, + void **edid) +{ + struct acpi_video_bus *video; + struct acpi_video_device *video_device; + union acpi_object *buffer = NULL; + acpi_status status; + int i, length; + + if (!device || !acpi_driver_data(device)) + return -EINVAL; + + video = acpi_driver_data(device); + + for (i = 0; i < video->attached_count; i++) { + video_device = video->attached_array[i].bind_info; + length = 256; + + if (!video_device) + continue; + + if (type) { + switch (type) { + case ACPI_VIDEO_DISPLAY_CRT: + if (!video_device->flags.crt) + continue; + break; + case ACPI_VIDEO_DISPLAY_TV: + if (!video_device->flags.tvout) + continue; + break; + case ACPI_VIDEO_DISPLAY_DVI: + if (!video_device->flags.dvi) + continue; + break; + case ACPI_VIDEO_DISPLAY_LCD: + if (!video_device->flags.lcd) + continue; + break; + } + } else if (video_device->device_id != device_id) { + continue; + } + + status = acpi_video_device_EDID(video_device, &buffer, length); + + if (ACPI_FAILURE(status) || !buffer || + buffer->type != ACPI_TYPE_BUFFER) { + length = 128; + status = acpi_video_device_EDID(video_device, &buffer, + length); + if (ACPI_FAILURE(status) || !buffer || + buffer->type != ACPI_TYPE_BUFFER) { + continue; + } + } + + *edid = buffer->buffer.pointer; + return length; + } + + return -ENODEV; +} +EXPORT_SYMBOL(acpi_video_get_edid); + static int acpi_video_bus_get_devices(struct acpi_video_bus *video, struct acpi_device *device) diff --git a/include/acpi/video.h b/include/acpi/video.h index cf7be3dd157b..551793c9b6e8 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h @@ -1,12 +1,28 @@ #ifndef __ACPI_VIDEO_H #define __ACPI_VIDEO_H +#define ACPI_VIDEO_DISPLAY_CRT 1 +#define ACPI_VIDEO_DISPLAY_TV 2 +#define ACPI_VIDEO_DISPLAY_DVI 3 +#define ACPI_VIDEO_DISPLAY_LCD 4 + +#define ACPI_VIDEO_DISPLAY_LEGACY_MONITOR 0x0100 +#define ACPI_VIDEO_DISPLAY_LEGACY_PANEL 0x0110 +#define ACPI_VIDEO_DISPLAY_LEGACY_TV 0x0200 + #if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE) extern int acpi_video_register(void); extern void acpi_video_unregister(void); +extern int acpi_video_get_edid(struct acpi_device *device, int type, + int device_id, void **edid); #else static inline int acpi_video_register(void) { return 0; } static inline void acpi_video_unregister(void) { return; } +static inline int acpi_video_get_edid(struct acpi_device *device, int type, + int device_id, void **edid) +{ + return -ENODEV; +} #endif #endif -- cgit v1.2.3-71-gd317 From 9b9ade6b612e562c4a5bd02ef38cc32e10f3f9ba Mon Sep 17 00:00:00 2001 From: Yulia Vilensky Date: Mon, 26 Apr 2010 14:05:25 +0300 Subject: ds2782_battery: Add support for ds2786 battery gas gauge Signed-off-by: Yulia Vilensky Signed-off-by: Mike Rapoport Signed-off-by: Anton Vorontsov --- drivers/power/Kconfig | 4 +- drivers/power/ds2782_battery.c | 184 ++++++++++++++++++++++++++++++----------- include/linux/ds2782_battery.h | 8 ++ 3 files changed, 146 insertions(+), 50 deletions(-) create mode 100644 include/linux/ds2782_battery.h (limited to 'include') diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 22f2fa912127..c59bcb7c6eb0 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -65,10 +65,10 @@ config BATTERY_DS2760 Say Y here to enable support for batteries with ds2760 chip. config BATTERY_DS2782 - tristate "DS2782 standalone gas-gauge" + tristate "DS2782/DS2786 standalone gas-gauge" depends on I2C help - Say Y here to enable support for the DS2782 standalone battery + Say Y here to enable support for the DS2782/DS2786 standalone battery gas-gauge. config BATTERY_PMU diff --git a/drivers/power/ds2782_battery.c b/drivers/power/ds2782_battery.c index ba1bd1a545be..c665e8007235 100644 --- a/drivers/power/ds2782_battery.c +++ b/drivers/power/ds2782_battery.c @@ -5,6 +5,8 @@ * * Author: Ryan Mallon * + * DS2786 added by Yulia Vilensky + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. @@ -20,12 +22,13 @@ #include #include #include +#include #define DS2782_REG_RARC 0x06 /* Remaining active relative capacity */ -#define DS2782_REG_VOLT_MSB 0x0c -#define DS2782_REG_TEMP_MSB 0x0a -#define DS2782_REG_CURRENT_MSB 0x0e +#define DS278x_REG_VOLT_MSB 0x0c +#define DS278x_REG_TEMP_MSB 0x0a +#define DS278x_REG_CURRENT_MSB 0x0e /* EEPROM Block */ #define DS2782_REG_RSNSP 0x69 /* Sense resistor value */ @@ -33,18 +36,33 @@ /* Current unit measurement in uA for a 1 milli-ohm sense resistor */ #define DS2782_CURRENT_UNITS 1563 -#define to_ds2782_info(x) container_of(x, struct ds2782_info, battery) +#define DS2786_REG_RARC 0x02 /* Remaining active relative capacity */ + +#define DS2786_CURRENT_UNITS 25 + +struct ds278x_info; + +struct ds278x_battery_ops { + int (*get_current)(struct ds278x_info *info, int *current_uA); + int (*get_voltage)(struct ds278x_info *info, int *voltage_uA); + int (*get_capacity)(struct ds278x_info *info, int *capacity_uA); + +}; + +#define to_ds278x_info(x) container_of(x, struct ds278x_info, battery) -struct ds2782_info { +struct ds278x_info { struct i2c_client *client; struct power_supply battery; + struct ds278x_battery_ops *ops; int id; + int rsns; }; static DEFINE_IDR(battery_id); static DEFINE_MUTEX(battery_lock); -static inline int ds2782_read_reg(struct ds2782_info *info, int reg, u8 *val) +static inline int ds278x_read_reg(struct ds278x_info *info, int reg, u8 *val) { int ret; @@ -58,7 +76,7 @@ static inline int ds2782_read_reg(struct ds2782_info *info, int reg, u8 *val) return 0; } -static inline int ds2782_read_reg16(struct ds2782_info *info, int reg_msb, +static inline int ds278x_read_reg16(struct ds278x_info *info, int reg_msb, s16 *val) { int ret; @@ -73,7 +91,7 @@ static inline int ds2782_read_reg16(struct ds2782_info *info, int reg_msb, return 0; } -static int ds2782_get_temp(struct ds2782_info *info, int *temp) +static int ds278x_get_temp(struct ds278x_info *info, int *temp) { s16 raw; int err; @@ -84,14 +102,14 @@ static int ds2782_get_temp(struct ds2782_info *info, int *temp) * celsius. The temperature value is stored as a 10 bit number, plus * sign in the upper bits of a 16 bit register. */ - err = ds2782_read_reg16(info, DS2782_REG_TEMP_MSB, &raw); + err = ds278x_read_reg16(info, DS278x_REG_TEMP_MSB, &raw); if (err) return err; *temp = ((raw / 32) * 125) / 100; return 0; } -static int ds2782_get_current(struct ds2782_info *info, int *current_uA) +static int ds2782_get_current(struct ds278x_info *info, int *current_uA) { int sense_res; int err; @@ -102,7 +120,7 @@ static int ds2782_get_current(struct ds2782_info *info, int *current_uA) * The units of measurement for current are dependent on the value of * the sense resistor. */ - err = ds2782_read_reg(info, DS2782_REG_RSNSP, &sense_res_raw); + err = ds278x_read_reg(info, DS2782_REG_RSNSP, &sense_res_raw); if (err) return err; if (sense_res_raw == 0) { @@ -113,14 +131,14 @@ static int ds2782_get_current(struct ds2782_info *info, int *current_uA) dev_dbg(&info->client->dev, "sense resistor = %d milli-ohms\n", sense_res); - err = ds2782_read_reg16(info, DS2782_REG_CURRENT_MSB, &raw); + err = ds278x_read_reg16(info, DS278x_REG_CURRENT_MSB, &raw); if (err) return err; *current_uA = raw * (DS2782_CURRENT_UNITS / sense_res); return 0; } -static int ds2782_get_voltage(struct ds2782_info *info, int *voltage_uA) +static int ds2782_get_voltage(struct ds278x_info *info, int *voltage_uA) { s16 raw; int err; @@ -129,36 +147,77 @@ static int ds2782_get_voltage(struct ds2782_info *info, int *voltage_uA) * Voltage is measured in units of 4.88mV. The voltage is stored as * a 10-bit number plus sign, in the upper bits of a 16-bit register */ - err = ds2782_read_reg16(info, DS2782_REG_VOLT_MSB, &raw); + err = ds278x_read_reg16(info, DS278x_REG_VOLT_MSB, &raw); if (err) return err; *voltage_uA = (raw / 32) * 4800; return 0; } -static int ds2782_get_capacity(struct ds2782_info *info, int *capacity) +static int ds2782_get_capacity(struct ds278x_info *info, int *capacity) { int err; u8 raw; - err = ds2782_read_reg(info, DS2782_REG_RARC, &raw); + err = ds278x_read_reg(info, DS2782_REG_RARC, &raw); if (err) return err; *capacity = raw; return raw; } -static int ds2782_get_status(struct ds2782_info *info, int *status) +static int ds2786_get_current(struct ds278x_info *info, int *current_uA) +{ + int err; + s16 raw; + + err = ds278x_read_reg16(info, DS278x_REG_CURRENT_MSB, &raw); + if (err) + return err; + *current_uA = (raw / 16) * (DS2786_CURRENT_UNITS / info->rsns); + return 0; +} + +static int ds2786_get_voltage(struct ds278x_info *info, int *voltage_uA) +{ + s16 raw; + int err; + + /* + * Voltage is measured in units of 1.22mV. The voltage is stored as + * a 10-bit number plus sign, in the upper bits of a 16-bit register + */ + err = ds278x_read_reg16(info, DS278x_REG_VOLT_MSB, &raw); + if (err) + return err; + *voltage_uA = (raw / 8) * 1220; + return 0; +} + +static int ds2786_get_capacity(struct ds278x_info *info, int *capacity) +{ + int err; + u8 raw; + + err = ds278x_read_reg(info, DS2786_REG_RARC, &raw); + if (err) + return err; + /* Relative capacity is displayed with resolution 0.5 % */ + *capacity = raw/2 ; + return 0; +} + +static int ds278x_get_status(struct ds278x_info *info, int *status) { int err; int current_uA; int capacity; - err = ds2782_get_current(info, ¤t_uA); + err = info->ops->get_current(info, ¤t_uA); if (err) return err; - err = ds2782_get_capacity(info, &capacity); + err = info->ops->get_capacity(info, &capacity); if (err) return err; @@ -174,32 +233,32 @@ static int ds2782_get_status(struct ds2782_info *info, int *status) return 0; } -static int ds2782_battery_get_property(struct power_supply *psy, +static int ds278x_battery_get_property(struct power_supply *psy, enum power_supply_property prop, union power_supply_propval *val) { - struct ds2782_info *info = to_ds2782_info(psy); + struct ds278x_info *info = to_ds278x_info(psy); int ret; switch (prop) { case POWER_SUPPLY_PROP_STATUS: - ret = ds2782_get_status(info, &val->intval); + ret = ds278x_get_status(info, &val->intval); break; case POWER_SUPPLY_PROP_CAPACITY: - ret = ds2782_get_capacity(info, &val->intval); + ret = info->ops->get_capacity(info, &val->intval); break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: - ret = ds2782_get_voltage(info, &val->intval); + ret = info->ops->get_voltage(info, &val->intval); break; case POWER_SUPPLY_PROP_CURRENT_NOW: - ret = ds2782_get_current(info, &val->intval); + ret = info->ops->get_current(info, &val->intval); break; case POWER_SUPPLY_PROP_TEMP: - ret = ds2782_get_temp(info, &val->intval); + ret = ds278x_get_temp(info, &val->intval); break; default: @@ -209,7 +268,7 @@ static int ds2782_battery_get_property(struct power_supply *psy, return ret; } -static enum power_supply_property ds2782_battery_props[] = { +static enum power_supply_property ds278x_battery_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_VOLTAGE_NOW, @@ -217,18 +276,18 @@ static enum power_supply_property ds2782_battery_props[] = { POWER_SUPPLY_PROP_TEMP, }; -static void ds2782_power_supply_init(struct power_supply *battery) +static void ds278x_power_supply_init(struct power_supply *battery) { battery->type = POWER_SUPPLY_TYPE_BATTERY; - battery->properties = ds2782_battery_props; - battery->num_properties = ARRAY_SIZE(ds2782_battery_props); - battery->get_property = ds2782_battery_get_property; + battery->properties = ds278x_battery_props; + battery->num_properties = ARRAY_SIZE(ds278x_battery_props); + battery->get_property = ds278x_battery_get_property; battery->external_power_changed = NULL; } -static int ds2782_battery_remove(struct i2c_client *client) +static int ds278x_battery_remove(struct i2c_client *client) { - struct ds2782_info *info = i2c_get_clientdata(client); + struct ds278x_info *info = i2c_get_clientdata(client); power_supply_unregister(&info->battery); kfree(info->battery.name); @@ -241,13 +300,36 @@ static int ds2782_battery_remove(struct i2c_client *client) return 0; } -static int ds2782_battery_probe(struct i2c_client *client, +static struct ds278x_battery_ops ds278x_ops[] = { + [0] = { + .get_current = ds2782_get_current, + .get_voltage = ds2782_get_voltage, + .get_capacity = ds2782_get_capacity, + }, + [1] = { + .get_current = ds2786_get_current, + .get_voltage = ds2786_get_voltage, + .get_capacity = ds2786_get_capacity, + } +}; + +static int ds278x_battery_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct ds2782_info *info; + struct ds278x_platform_data *pdata = client->dev.platform_data; + struct ds278x_info *info; int ret; int num; + /* + * ds2786 should have the sense resistor value set + * in the platform data + */ + if (id->driver_data == 1 && !pdata) { + dev_err(&client->dev, "missing platform data for ds2786\n"); + return -EINVAL; + } + /* Get an ID for this battery */ ret = idr_pre_get(&battery_id, GFP_KERNEL); if (ret == 0) { @@ -267,15 +349,20 @@ static int ds2782_battery_probe(struct i2c_client *client, goto fail_info; } - info->battery.name = kasprintf(GFP_KERNEL, "ds2782-%d", num); + info->battery.name = kasprintf(GFP_KERNEL, "%s-%d", client->name, num); if (!info->battery.name) { ret = -ENOMEM; goto fail_name; } + if (id->driver_data == 1) + info->rsns = pdata->rsns; + i2c_set_clientdata(client, info); info->client = client; - ds2782_power_supply_init(&info->battery); + info->id = num; + info->ops = &ds278x_ops[id->driver_data]; + ds278x_power_supply_init(&info->battery); ret = power_supply_register(&client->dev, &info->battery); if (ret) { @@ -297,31 +384,32 @@ fail_id: return ret; } -static const struct i2c_device_id ds2782_id[] = { +static const struct i2c_device_id ds278x_id[] = { {"ds2782", 0}, + {"ds2786", 1}, {}, }; -static struct i2c_driver ds2782_battery_driver = { +static struct i2c_driver ds278x_battery_driver = { .driver = { .name = "ds2782-battery", }, - .probe = ds2782_battery_probe, - .remove = ds2782_battery_remove, - .id_table = ds2782_id, + .probe = ds278x_battery_probe, + .remove = ds278x_battery_remove, + .id_table = ds278x_id, }; -static int __init ds2782_init(void) +static int __init ds278x_init(void) { - return i2c_add_driver(&ds2782_battery_driver); + return i2c_add_driver(&ds278x_battery_driver); } -module_init(ds2782_init); +module_init(ds278x_init); -static void __exit ds2782_exit(void) +static void __exit ds278x_exit(void) { - i2c_del_driver(&ds2782_battery_driver); + i2c_del_driver(&ds278x_battery_driver); } -module_exit(ds2782_exit); +module_exit(ds278x_exit); MODULE_AUTHOR("Ryan Mallon "); MODULE_DESCRIPTION("Maxim/Dallas DS2782 Stand-Alone Fuel Gauage IC driver"); diff --git a/include/linux/ds2782_battery.h b/include/linux/ds2782_battery.h new file mode 100644 index 000000000000..b4e281f65c15 --- /dev/null +++ b/include/linux/ds2782_battery.h @@ -0,0 +1,8 @@ +#ifndef __LINUX_DS2782_BATTERY_H +#define __LINUX_DS2782_BATTERY_H + +struct ds278x_platform_data { + int rsns; +}; + +#endif -- cgit v1.2.3-71-gd317 From cf32eb89cb4e674f88e4af5025839d85d02485c6 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:25 -0700 Subject: of/flattree: make of_fdt.h safe to unconditionally include. If CONFIG_OF_FLATTREE is not set, then don't process the body of linux/of_fdt.h Signed-off-by: Grant Likely --- include/linux/of_fdt.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index a1ca92ccb0ff..f0fdd1f43688 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h @@ -57,6 +57,7 @@ struct boot_param_header { __be32 dt_struct_size; /* size of the DT structure block */ }; +#if defined(CONFIG_OF_FLATTREE) /* TBD: Temporary export of fdt globals - remove when code fully merged */ extern int __initdata dt_root_addr_cells; extern int __initdata dt_root_size_cells; @@ -98,6 +99,7 @@ extern int early_init_dt_scan_root(unsigned long node, const char *uname, /* Other Prototypes */ extern void unflatten_device_tree(void); extern void early_init_devtree(void *); +#endif /* CONFIG_OF_FLATTREE */ #endif /* __ASSEMBLY__ */ #endif /* _LINUX_OF_FDT_H */ -- cgit v1.2.3-71-gd317 From 8bfe9b5c3a684fe39eb58a65e466c103d1c32c9a Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:26 -0700 Subject: of/flattree: Make unflatten_device_tree() safe to call from any arch This patch makes unflatten_device_tree() safe to call from any arch setup code with the following changes: - Make sure initial_boot_params actually points to a device tree blob before unflattening - Make sure the initial_boot_params->magic field is correct - If CONFIG_OF_FLATTREE is not set, then make unflatten_device_tree() an empty static inline function. This patch also adds some additional debug output to the top of unflatten_device_tree(). Signed-off-by: Grant Likely --- drivers/of/fdt.c | 15 +++++++++++++++ include/linux/of_fdt.h | 2 ++ 2 files changed, 17 insertions(+) (limited to 'include') diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index dee4fb56b094..b6987bba8556 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -556,6 +556,21 @@ void __init unflatten_device_tree(void) pr_debug(" -> unflatten_device_tree()\n"); + if (!initial_boot_params) { + pr_debug("No device tree pointer\n"); + return; + } + + pr_debug("Unflattening device tree:\n"); + pr_debug("magic: %08x\n", be32_to_cpu(initial_boot_params->magic)); + pr_debug("size: %08x\n", be32_to_cpu(initial_boot_params->totalsize)); + pr_debug("version: %08x\n", be32_to_cpu(initial_boot_params->version)); + + if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) { + pr_err("Invalid device tree blob header\n"); + return; + } + /* First pass, scan for size */ start = ((unsigned long)initial_boot_params) + be32_to_cpu(initial_boot_params->off_dt_struct); diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index f0fdd1f43688..71e1a916d3fa 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h @@ -99,6 +99,8 @@ extern int early_init_dt_scan_root(unsigned long node, const char *uname, /* Other Prototypes */ extern void unflatten_device_tree(void); extern void early_init_devtree(void *); +#else /* CONFIG_OF_FLATTREE */ +static inline void unflatten_device_tree(void) {} #endif /* CONFIG_OF_FLATTREE */ #endif /* __ASSEMBLY__ */ -- cgit v1.2.3-71-gd317 From efb2e014fc4f2675011b802e1a84bf9a58756004 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:27 -0700 Subject: of: protect contents of of_platform.h and of_device.h Only process contents of of_platform.h and of_device.h if CONFIG_OF_DEVICE is set. Signed-off-by: Grant Likely --- include/linux/of_device.h | 2 ++ include/linux/of_platform.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/of_device.h b/include/linux/of_device.h index d3a74e00a3e1..e7904a9cd3a3 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -1,6 +1,7 @@ #ifndef _LINUX_OF_DEVICE_H #define _LINUX_OF_DEVICE_H +#ifdef CONFIG_OF_DEVICE #include #include #include @@ -26,5 +27,6 @@ static inline void of_device_free(struct of_device *dev) extern ssize_t of_device_get_modalias(struct of_device *ofdev, char *str, ssize_t len); +#endif /* CONFIG_OF_DEVICE */ #endif /* _LINUX_OF_DEVICE_H */ diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 908406651330..ac3ae0758fbe 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -11,6 +11,7 @@ * */ +#ifdef CONFIG_OF_DEVICE #include #include #include @@ -66,5 +67,6 @@ static inline void of_unregister_platform_driver(struct of_platform_driver *drv) extern struct of_device *of_find_device_by_node(struct device_node *np); extern int of_bus_type_init(struct bus_type *bus, const char *name); +#endif /* CONFIG_OF_DEVICE */ #endif /* _LINUX_OF_PLATFORM_H */ -- cgit v1.2.3-71-gd317 From d706c1b050274b3bf97d7cb0542c0d070c9ccb8b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:28 -0700 Subject: driver-core: Add device node pointer to struct device Currently, platforms using CONFIG_OF add a 'struct device_node *of_node' to dev->archdata. However, with CONFIG_OF becoming generic for all architectures, it makes sense for commonality to move it out of archdata and into struct device proper. This patch adds a struct device_node *of_node member to struct device and updates all locations which currently write the device_node pointer into archdata to also update dev->of_node. Subsequent patches will modify callers to use the archdata location and ultimately remove the archdata member entirely. Signed-off-by: Grant Likely Acked-by: Greg Kroah-Hartman CC: Michal Simek CC: Greg Kroah-Hartman CC: Benjamin Herrenschmidt CC: "David S. Miller" CC: Stephen Rothwell CC: Jeremy Kerr CC: microblaze-uclinux@itee.uq.edu.au CC: linux-kernel@vger.kernel.org CC: linuxppc-dev@ozlabs.org CC: sparclinux@vger.kernel.org --- arch/microblaze/kernel/of_device.c | 1 + arch/powerpc/kernel/of_device.c | 1 + arch/powerpc/kernel/pci-common.c | 3 ++- arch/powerpc/kernel/vio.c | 3 ++- arch/powerpc/platforms/ps3/system-bus.c | 1 + arch/sparc/kernel/of_device_32.c | 1 + arch/sparc/kernel/of_device_64.c | 1 + arch/sparc/kernel/pci.c | 1 + drivers/of/of_mdio.c | 1 + drivers/of/of_spi.c | 1 + include/linux/device.h | 4 ++++ 11 files changed, 16 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c index 9a0f7632c47c..f6c521898ebf 100644 --- a/arch/microblaze/kernel/of_device.c +++ b/arch/microblaze/kernel/of_device.c @@ -54,6 +54,7 @@ struct of_device *of_device_alloc(struct device_node *np, dev->dev.parent = parent; dev->dev.release = of_release_dev; dev->dev.archdata.of_node = np; + dev->dev.of_node = np; if (bus_id) dev_set_name(&dev->dev, bus_id); diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index a359cb08e900..9577e6f4e3bf 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -74,6 +74,7 @@ struct of_device *of_device_alloc(struct device_node *np, dev->dev.parent = parent; dev->dev.release = of_release_dev; dev->dev.archdata.of_node = np; + dev->dev.of_node = np; if (bus_id) dev_set_name(&dev->dev, "%s", bus_id); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 0c0567e58409..88da282047c3 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1097,8 +1097,9 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) if (dev->is_added) continue; - /* Setup OF node pointer in archdata */ + /* Setup OF node pointer in the device */ sd->of_node = pci_device_to_OF_node(dev); + dev->dev.of_node = pci_device_to_OF_node(dev); /* Fixup NUMA node as it may not be setup yet by the generic * code and is needed by the DMA init diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 82237176a2a3..d6708da114ee 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -1230,7 +1230,8 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) if (unit_address != NULL) viodev->unit_address = *unit_address; } - viodev->dev.archdata.of_node = of_node_get(of_node); + viodev->dev.of_node = of_node_get(of_node); + viodev->dev.archdata.of_node = viodev->dev.of_node; if (firmware_has_feature(FW_FEATURE_CMO)) vio_cmo_set_dma_ops(viodev); diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index 6d09f5e3e7e4..e546c86a539b 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -766,6 +766,7 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) BUG(); }; + dev->core.of_node = NULL; dev->core.archdata.of_node = NULL; set_dev_node(&dev->core, 0); diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index da527b33ebc7..4926c1babd84 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -348,6 +348,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, sd->prom_node = dp; sd->op = op; + op->dev.of_node = dp; op->node = dp; op->clock_freq = of_getintprop_default(dp, "clock-frequency", diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index b3d4cb5d21b3..5bc74161667c 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -643,6 +643,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, sd->prom_node = dp; sd->op = op; + op->dev.of_node = dp; op->node = dp; op->clock_freq = of_getintprop_default(dp, "clock-frequency", diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 5ac539a5930f..0c920147b4ef 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -262,6 +262,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, sd->stc = &pbm->stc; sd->host_controller = pbm; sd->prom_node = node; + dev->dev.of_node = node; sd->op = op = of_find_device_by_node(node); sd->numa_node = pbm->numa_node; diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 18ecae4a4375..12090f57dc87 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -80,6 +80,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) * can be looked up later */ of_node_get(child); dev_archdata_set_node(&phy->dev.archdata, child); + phy->dev.of_node = child; /* All data is now stored in the phy struct; register it */ rc = phy_device_register(phy); diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c index f65f48b98448..f3119a0836af 100644 --- a/drivers/of/of_spi.c +++ b/drivers/of/of_spi.c @@ -79,6 +79,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) /* Store a pointer to the node in the device structure */ of_node_get(nc); + spi->dev.of_node = nc; spi->dev.archdata.of_node = nc; /* Register the new device */ diff --git a/include/linux/device.h b/include/linux/device.h index 182192892d45..7a968bdb02e2 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -34,6 +34,7 @@ struct class; struct class_private; struct bus_type; struct bus_type_private; +struct device_node; struct bus_attribute { struct attribute attr; @@ -433,6 +434,9 @@ struct device { override */ /* arch specific additions */ struct dev_archdata archdata; +#ifdef CONFIG_OF + struct device_node *of_node; +#endif dev_t devt; /* dev_t, creates the sysfs "dev" */ -- cgit v1.2.3-71-gd317 From d12d42f744f805a9ccc33cd76f04b237cd83ce56 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 13 Apr 2010 16:12:28 -0700 Subject: i2c/of: Allow device node to be passed via i2c_board_info The struct device_node *of_node pointer is moving out of dev->archdata and into the struct device proper. of_i2c.c needs to set the of_node pointer before the device is registered. Since the i2c subsystem doesn't allow 2 stage allocation and registration of i2c devices, the of_node pointer needs to be passed via the i2c_board_info structure so that it is set prior to registration. This patch adds of_node to struct i2c_board_info (conditional on CONFIG_OF), sets of_node in i2c_new_device(), and modifies of_i2c.c to use the new parameter. The calling of dev_archdata_set_node() from of_i2c will be removed in a subsequent patch when of_node is removed from archdata and all users are converted over. Signed-off-by: Grant Likely --- drivers/i2c/i2c-core.c | 3 +++ drivers/of/of_i2c.c | 1 + include/linux/i2c.h | 4 ++++ 3 files changed, 8 insertions(+) (limited to 'include') diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 3202a86f420e..4099b2b8c392 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -387,6 +387,9 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) client->dev.parent = &client->adapter->dev; client->dev.bus = &i2c_bus_type; client->dev.type = &i2c_client_type; +#ifdef CONFIG_OF + client->dev.of_node = info->of_node; +#endif dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), client->addr); diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index a3a708e590d0..e690a2aa6fef 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -43,6 +43,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap, info.addr = be32_to_cpup(addr); dev_archdata_set_node(&dev_ad, node); + info.of_node = node; info.archdata = &dev_ad; request_module("%s", info.type); diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 0a5da639b327..4f37ff1de7e1 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -34,6 +34,7 @@ #include /* for struct device */ #include /* for completion */ #include +#include /* for struct device_node */ extern struct bus_type i2c_bus_type; @@ -251,6 +252,9 @@ struct i2c_board_info { unsigned short addr; void *platform_data; struct dev_archdata *archdata; +#ifdef CONFIG_OF + struct device_node *of_node; +#endif int irq; }; -- cgit v1.2.3-71-gd317 From b6dacf63e9fb2e7a1369843d6cef332f76fca6a3 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 11 May 2010 13:49:25 -0400 Subject: ACPI: Unconditionally set SCI_EN on resume The ACPI spec tells us that the firmware will reenable SCI_EN on resume. Reality disagrees in some cases. The ACPI spec tells us that the only way to set SCI_EN is via an SMM call. https://bugzilla.kernel.org/show_bug.cgi?id=13745 shows us that doing so may break machines. Tracing the ACPI calls made by Windows shows that it unconditionally sets SCI_EN on resume with a direct register write, and therefore the overwhelming probability is that everything is fine with this behaviour. Signed-off-by: Matthew Garrett Tested-by: Rafael J. Wysocki Signed-off-by: Len Brown --- arch/x86/kernel/acpi/sleep.c | 2 - drivers/acpi/sleep.c | 157 +------------------------------------------ include/linux/acpi.h | 1 - 3 files changed, 2 insertions(+), 158 deletions(-) (limited to 'include') diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index f9961034e557..82e508677b91 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -162,8 +162,6 @@ static int __init acpi_sleep_setup(char *str) #endif if (strncmp(str, "old_ordering", 12) == 0) acpi_old_suspend_ordering(); - if (strncmp(str, "sci_force_enable", 16) == 0) - acpi_set_sci_en_on_resume(); str = strchr(str, ','); if (str != NULL) str += strspn(str, ", \t"); diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index baa76bbf244a..4ab2275b4461 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -80,22 +80,6 @@ static int acpi_sleep_prepare(u32 acpi_state) #ifdef CONFIG_ACPI_SLEEP static u32 acpi_target_sleep_state = ACPI_STATE_S0; -/* - * According to the ACPI specification the BIOS should make sure that ACPI is - * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, - * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI - * on such systems during resume. Unfortunately that doesn't help in - * particularly pathological cases in which SCI_EN has to be set directly on - * resume, although the specification states very clearly that this flag is - * owned by the hardware. The set_sci_en_on_resume variable will be set in such - * cases. - */ -static bool set_sci_en_on_resume; - -void __init acpi_set_sci_en_on_resume(void) -{ - set_sci_en_on_resume = true; -} /* * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the @@ -253,11 +237,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) break; } - /* If ACPI is not enabled by the BIOS, we need to enable it here. */ - if (set_sci_en_on_resume) - acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); - else - acpi_enable(); + /* This violates the spec but is required for bug compatibility. */ + acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); /* Reprogram control registers and execute _BFS */ acpi_leave_sleep_state_prep(acpi_state); @@ -346,12 +327,6 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d) return 0; } -static int __init init_set_sci_en_on_resume(const struct dmi_system_id *d) -{ - set_sci_en_on_resume = true; - return 0; -} - static struct dmi_system_id __initdata acpisleep_dmi_table[] = { { .callback = init_old_suspend_ordering, @@ -370,22 +345,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { }, }, { - .callback = init_set_sci_en_on_resume, - .ident = "Apple MacBook 1,1", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Apple MacMini 1,1", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), - }, - }, - { .callback = init_old_suspend_ordering, .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)", .matches = { @@ -394,94 +353,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { }, }, { - .callback = init_set_sci_en_on_resume, - .ident = "Toshiba Satellite L300", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard HP G7000 Notebook PC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP G7000 Notebook PC"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard HP Pavilion dv3 Notebook PC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv3 Notebook PC"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard Pavilion dv4", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard Pavilion dv7", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard Compaq Presario C700 Notebook PC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario C700 Notebook PC"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Hewlett-Packard Compaq Presario CQ40 Notebook PC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario CQ40 Notebook PC"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Lenovo ThinkPad T410", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T410"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Lenovo ThinkPad T510", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T510"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Lenovo ThinkPad W510", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W510"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Lenovo ThinkPad X201[s]", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201"), - }, - }, - { .callback = init_old_suspend_ordering, .ident = "Panasonic CF51-2L", .matches = { @@ -490,30 +361,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), }, }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Dell Studio 1558", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1558"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Dell Studio 1557", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1557"), - }, - }, - { - .callback = init_set_sci_en_on_resume, - .ident = "Dell Studio 1555", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1555"), - }, - }, {}, }; #endif /* CONFIG_SUSPEND */ diff --git a/include/linux/acpi.h b/include/linux/acpi.h index b926afe8c03e..87ca4913294c 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -251,7 +251,6 @@ int acpi_check_mem_region(resource_size_t start, resource_size_t n, void __init acpi_no_s4_hw_signature(void); void __init acpi_old_suspend_ordering(void); void __init acpi_s4_no_nvs(void); -void __init acpi_set_sci_en_on_resume(void); #endif /* CONFIG_PM_SLEEP */ struct acpi_osc_context { -- cgit v1.2.3-71-gd317 From 8f0820183056ad26dabc0202115848a92f1143fc Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 20 Apr 2010 10:47:33 -0400 Subject: tracing: Create class struct for events This patch creates a ftrace_event_class struct that event structs point to. This class struct will be made to hold information to modify the events. Currently the class struct only holds the events system name. This patch slightly increases the size, but this change lays the ground work of other changes to make the footprint of tracepoints smaller. With 82 standard tracepoints, and 618 system call tracepoints (two tracepoints per syscall: enter and exit): text data bss dec hex filename 4913961 1088356 861512 6863829 68bbd5 vmlinux.orig 4914025 1088868 861512 6864405 68be15 vmlinux.class This patch also cleans up some stale comments in ftrace.h. v2: Fixed missing semi-colon in macro. Acked-by: Frederic Weisbecker Acked-by: Mathieu Desnoyers Acked-by: Masami Hiramatsu Signed-off-by: Steven Rostedt --- include/linux/ftrace_event.h | 6 +++++- include/linux/syscalls.h | 6 ++++-- include/trace/ftrace.h | 44 ++++++++++++++++---------------------- kernel/trace/trace_events.c | 20 ++++++++--------- kernel/trace/trace_events_filter.c | 6 +++--- kernel/trace/trace_export.c | 6 +++++- kernel/trace/trace_kprobe.c | 12 +++++------ kernel/trace/trace_syscalls.c | 4 ++++ 8 files changed, 56 insertions(+), 48 deletions(-) (limited to 'include') diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 39e71b0a3bfd..496eea898ee4 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -113,10 +113,14 @@ void tracing_record_cmdline(struct task_struct *tsk); struct event_filter; +struct ftrace_event_class { + char *system; +}; + struct ftrace_event_call { struct list_head list; + struct ftrace_event_class *class; char *name; - char *system; struct dentry *dir; struct trace_event *event; int enabled; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 057929b0a651..ac5791df2506 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -134,6 +134,8 @@ struct perf_event_attr; #define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__) #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) +extern struct ftrace_event_class event_class_syscalls; + #define SYSCALL_TRACE_ENTER_EVENT(sname) \ static const struct syscall_metadata __syscall_meta_##sname; \ static struct ftrace_event_call \ @@ -146,7 +148,7 @@ struct perf_event_attr; __attribute__((section("_ftrace_events"))) \ event_enter_##sname = { \ .name = "sys_enter"#sname, \ - .system = "syscalls", \ + .class = &event_class_syscalls, \ .event = &enter_syscall_print_##sname, \ .raw_init = init_syscall_trace, \ .define_fields = syscall_enter_define_fields, \ @@ -168,7 +170,7 @@ struct perf_event_attr; __attribute__((section("_ftrace_events"))) \ event_exit_##sname = { \ .name = "sys_exit"#sname, \ - .system = "syscalls", \ + .class = &event_class_syscalls, \ .event = &exit_syscall_print_##sname, \ .raw_init = init_syscall_trace, \ .define_fields = syscall_exit_define_fields, \ diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 75dd7787fb37..7dcdfd824aab 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -62,7 +62,10 @@ struct trace_entry ent; \ tstruct \ char __data[0]; \ - }; + }; \ + \ + static struct ftrace_event_class event_class_##name; + #undef DEFINE_EVENT #define DEFINE_EVENT(template, name, proto, args) \ static struct ftrace_event_call \ @@ -430,22 +433,6 @@ perf_trace_disable_##name(struct ftrace_event_call *unused) \ * * Override the macros in to include the following: * - * static void ftrace_event_(proto) - * { - * event_trace_printk(_RET_IP_, ": " ); - * } - * - * static int ftrace_reg_event_(struct ftrace_event_call *unused) - * { - * return register_trace_(ftrace_event_); - * } - * - * static void ftrace_unreg_event_(struct ftrace_event_call *unused) - * { - * unregister_trace_(ftrace_event_); - * } - * - * * For those macros defined with TRACE_EVENT: * * static struct ftrace_event_call event_; @@ -497,17 +484,21 @@ perf_trace_disable_##name(struct ftrace_event_call *unused) \ * * static const char print_fmt_[] = ; * + * static struct ftrace_event_class __used event_class_