diff options
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/Kconfig | 41 | ||||
-rw-r--r-- | drivers/misc/Makefile | 4 | ||||
-rw-r--r-- | drivers/misc/arm-charlcd.c | 396 | ||||
-rw-r--r-- | drivers/misc/bh1780gli.c | 273 | ||||
-rw-r--r-- | drivers/misc/bmp085.c | 482 | ||||
-rw-r--r-- | drivers/misc/cs5535-mfgpt.c | 11 | ||||
-rw-r--r-- | drivers/misc/enclosure.c | 7 | ||||
-rw-r--r-- | drivers/misc/hmc6352.c | 166 | ||||
-rw-r--r-- | drivers/misc/hpilo.c | 17 | ||||
-rw-r--r-- | drivers/misc/hpilo.h | 8 | ||||
-rw-r--r-- | drivers/misc/lkdtm.c | 4 |
11 files changed, 1391 insertions, 18 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 26386a92f5a..0b591b65824 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -72,7 +72,7 @@ config ATMEL_TCLIB config ATMEL_TCB_CLKSRC bool "TC Block Clocksource" - depends on ATMEL_TCLIB && GENERIC_TIME + depends on ATMEL_TCLIB default y help Select this to get a high precision clocksource based on a @@ -240,7 +240,7 @@ config CS5535_MFGPT_DEFAULT_IRQ config CS5535_CLOCK_EVENT_SRC tristate "CS5535/CS5536 high-res timer (MFGPT) events" - depends on GENERIC_TIME && GENERIC_CLOCKEVENTS && CS5535_MFGPT + depends on GENERIC_CLOCKEVENTS && CS5535_MFGPT help This driver provides a clock event source based on the MFGPT timer(s) in the CS5535 and CS5536 companion chips. @@ -304,6 +304,23 @@ config SENSORS_TSL2550 This driver can also be built as a module. If so, the module will be called tsl2550. +config SENSORS_BH1780 + tristate "ROHM BH1780GLI ambient light sensor" + depends on I2C && SYSFS + help + If you say yes here you get support for the ROHM BH1780GLI + ambient light sensor. + + This driver can also be built as a module. If so, the module + will be called bh1780gli. + +config HMC6352 + tristate "Honeywell HMC6352 compass" + depends on I2C + help + This driver provides support for the Honeywell HMC6352 compass, + providing configuration and heading data via sysfs. + config EP93XX_PWM tristate "EP93xx PWM support" depends on ARCH_EP93XX @@ -353,6 +370,26 @@ config VMWARE_BALLOON To compile this driver as a module, choose M here: the module will be called vmware_balloon. +config ARM_CHARLCD + bool "ARM Ltd. Character LCD Driver" + depends on PLAT_VERSATILE + help + This is a driver for the character LCD found on the ARM Ltd. + Versatile and RealView Platform Baseboards. It doesn't do + very much more than display the text "ARM Linux" on the first + line and the Linux version on the second line, but that's + still useful. + +config BMP085 + tristate "BMP085 digital pressure sensor" + depends on I2C && SYSFS + help + If you say yes here you get support for the Bosch Sensortec + BMP086 digital pressure sensor. + + To compile this driver as a module, choose M here: the + module will be called bmp085. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 6ed06a19474..255a80dc9d7 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -9,11 +9,13 @@ obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o +obj-$(CONFIG_BMP085) += bmp085.o obj-$(CONFIG_ICS932S401) += ics932s401.o obj-$(CONFIG_LKDTM) += lkdtm.o obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o obj-$(CONFIG_PHANTOM) += phantom.o +obj-$(CONFIG_SENSORS_BH1780) += bh1780gli.o obj-$(CONFIG_SGI_IOC4) += ioc4.o obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o obj-$(CONFIG_KGDB_TESTS) += kgdbts.o @@ -28,6 +30,8 @@ obj-$(CONFIG_DS1682) += ds1682.o obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o obj-$(CONFIG_C2PORT) += c2port/ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ +obj-$(CONFIG_HMC6352) += hmc6352.o obj-y += eeprom/ obj-y += cb710/ obj-$(CONFIG_VMWARE_BALLOON) += vmware_balloon.o +obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o diff --git a/drivers/misc/arm-charlcd.c b/drivers/misc/arm-charlcd.c new file mode 100644 index 00000000000..9e3879ef58f --- /dev/null +++ b/drivers/misc/arm-charlcd.c @@ -0,0 +1,396 @@ +/* + * Driver for the on-board character LCD found on some ARM reference boards + * This is basically an Hitachi HD44780 LCD with a custom IP block to drive it + * http://en.wikipedia.org/wiki/HD44780_Character_LCD + * Currently it will just display the text "ARM Linux" and the linux version + * + * License terms: GNU General Public License (GPL) version 2 + * Author: Linus Walleij <triad@df.lth.se> + */ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/completion.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/slab.h> +#include <linux/workqueue.h> +#include <generated/utsrelease.h> + +#define DRIVERNAME "arm-charlcd" +#define CHARLCD_TIMEOUT (msecs_to_jiffies(1000)) + +/* Offsets to registers */ +#define CHAR_COM 0x00U +#define CHAR_DAT 0x04U +#define CHAR_RD 0x08U +#define CHAR_RAW 0x0CU +#define CHAR_MASK 0x10U +#define CHAR_STAT 0x14U + +#define CHAR_RAW_CLEAR 0x00000000U +#define CHAR_RAW_VALID 0x00000100U + +/* Hitachi HD44780 display commands */ +#define HD_CLEAR 0x01U +#define HD_HOME 0x02U +#define HD_ENTRYMODE 0x04U +#define HD_ENTRYMODE_INCREMENT 0x02U +#define HD_ENTRYMODE_SHIFT 0x01U +#define HD_DISPCTRL 0x08U +#define HD_DISPCTRL_ON 0x04U +#define HD_DISPCTRL_CURSOR_ON 0x02U +#define HD_DISPCTRL_CURSOR_BLINK 0x01U +#define HD_CRSR_SHIFT 0x10U +#define HD_CRSR_SHIFT_DISPLAY 0x08U +#define HD_CRSR_SHIFT_DISPLAY_RIGHT 0x04U +#define HD_FUNCSET 0x20U +#define HD_FUNCSET_8BIT 0x10U +#define HD_FUNCSET_2_LINES 0x08U +#define HD_FUNCSET_FONT_5X10 0x04U +#define HD_SET_CGRAM 0x40U +#define HD_SET_DDRAM 0x80U +#define HD_BUSY_FLAG 0x80U + +/** + * @dev: a pointer back to containing device + * @phybase: the offset to the controller in physical memory + * @physize: the size of the physical page + * @virtbase: the offset to the controller in virtual memory + * @irq: reserved interrupt number + * @complete: completion structure for the last LCD command + */ +struct charlcd { + struct device *dev; + u32 phybase; + u32 physize; + void __iomem *virtbase; + int irq; + struct completion complete; + struct delayed_work init_work; +}; + +static irqreturn_t charlcd_interrupt(int irq, void *data) +{ + struct charlcd *lcd = data; + u8 status; + + status = readl(lcd->virtbase + CHAR_STAT) & 0x01; + /* Clear IRQ */ + writel(CHAR_RAW_CLEAR, lcd->virtbase + CHAR_RAW); + if (status) + complete(&lcd->complete); + else + dev_info(lcd->dev, "Spurious IRQ (%02x)\n", status); + return IRQ_HANDLED; +} + + +static void charlcd_wait_complete_irq(struct charlcd *lcd) +{ + int ret; + + ret = wait_for_completion_interruptible_timeout(&lcd->complete, + CHARLCD_TIMEOUT); + /* Disable IRQ after completion */ + writel(0x00, lcd->virtbase + CHAR_MASK); + + if (ret < 0) { + dev_err(lcd->dev, + "wait_for_completion_interruptible_timeout() " + "returned %d waiting for ready\n", ret); + return; + } + + if (ret == 0) { + dev_err(lcd->dev, "charlcd controller timed out " + "waiting for ready\n"); + return; + } +} + +static u8 charlcd_4bit_read_char(struct charlcd *lcd) +{ + u8 data; + u32 val; + int i; + + /* If we can, use an IRQ to wait for the data, else poll */ + if (lcd->irq >= 0) + charlcd_wait_complete_irq(lcd); + else { + i = 0; + val = 0; + while (!(val & CHAR_RAW_VALID) && i < 10) { + udelay(100); + val = readl(lcd->virtbase + CHAR_RAW); + i++; + } + + writel(CHAR_RAW_CLEAR, lcd->virtbase + CHAR_RAW); + } + msleep(1); + + /* Read the 4 high bits of the data */ + data = readl(lcd->virtbase + CHAR_RD) & 0xf0; + + /* + * The second read for the low bits does not trigger an IRQ + * so in this case we have to poll for the 4 lower bits + */ + i = 0; + val = 0; + while (!(val & CHAR_RAW_VALID) && i < 10) { + udelay(100); + val = readl(lcd->virtbase + CHAR_RAW); + i++; + } + writel(CHAR_RAW_CLEAR, lcd->virtbase + CHAR_RAW); + msleep(1); + + /* Read the 4 low bits of the data */ + data |= (readl(lcd->virtbase + CHAR_RD) >> 4) & 0x0f; + + return data; +} + +static bool charlcd_4bit_read_bf(struct charlcd *lcd) +{ + if (lcd->irq >= 0) { + /* + * If we'll use IRQs to wait for the busyflag, clear any + * pending flag and enable IRQ + */ + writel(CHAR_RAW_CLEAR, lcd->virtbase + CHAR_RAW); + init_completion(&lcd->complete); + writel(0x01, lcd->virtbase + CHAR_MASK); + } + readl(lcd->virtbase + CHAR_COM); + return charlcd_4bit_read_char(lcd) & HD_BUSY_FLAG ? true : false; +} + +static void charlcd_4bit_wait_busy(struct charlcd *lcd) +{ + int retries = 50; + + udelay(100); + while (charlcd_4bit_read_bf(lcd) && retries) + retries--; + if (!retries) + dev_err(lcd->dev, "timeout waiting for busyflag\n"); +} + +static void charlcd_4bit_command(struct charlcd *lcd, u8 cmd) +{ + u32 cmdlo = (cmd << 4) & 0xf0; + u32 cmdhi = (cmd & 0xf0); + + writel(cmdhi, lcd->virtbase + CHAR_COM); + udelay(10); + writel(cmdlo, lcd->virtbase + CHAR_COM); + charlcd_4bit_wait_busy(lcd); +} + +static void charlcd_4bit_char(struct charlcd *lcd, u8 ch) +{ + u32 chlo = (ch << 4) & 0xf0; + u32 chhi = (ch & 0xf0); + + writel(chhi, lcd->virtbase + CHAR_DAT); + udelay(10); + writel(chlo, lcd->virtbase + CHAR_DAT); + charlcd_4bit_wait_busy(lcd); +} + +static void charlcd_4bit_print(struct charlcd *lcd, int line, const char *str) +{ + u8 offset; + int i; + + /* + * We support line 0, 1 + * Line 1 runs from 0x00..0x27 + * Line 2 runs from 0x28..0x4f + */ + if (line == 0) + offset = 0; + else if (line == 1) + offset = 0x28; + else + return; + + /* Set offset */ + charlcd_4bit_command(lcd, HD_SET_DDRAM | offset); + + /* Send string */ + for (i = 0; i < strlen(str) && i < 0x28; i++) + charlcd_4bit_char(lcd, str[i]); +} + +static void charlcd_4bit_init(struct charlcd *lcd) +{ + /* These commands cannot be checked with the busy flag */ + writel(HD_FUNCSET | HD_FUNCSET_8BIT, lcd->virtbase + CHAR_COM); + msleep(5); + writel(HD_FUNCSET | HD_FUNCSET_8BIT, lcd->virtbase + CHAR_COM); + udelay(100); + writel(HD_FUNCSET | HD_FUNCSET_8BIT, lcd->virtbase + CHAR_COM); + udelay(100); + /* Go to 4bit mode */ + writel(HD_FUNCSET, lcd->virtbase + CHAR_COM); + udelay(100); + /* + * 4bit mode, 2 lines, 5x8 font, after this the number of lines + * and the font cannot be changed until the next initialization sequence + */ + charlcd_4bit_command(lcd, HD_FUNCSET | HD_FUNCSET_2_LINES); + charlcd_4bit_command(lcd, HD_DISPCTRL | HD_DISPCTRL_ON); + charlcd_4bit_command(lcd, HD_ENTRYMODE | HD_ENTRYMODE_INCREMENT); + charlcd_4bit_command(lcd, HD_CLEAR); + charlcd_4bit_command(lcd, HD_HOME); + /* Put something useful in the display */ + charlcd_4bit_print(lcd, 0, "ARM Linux"); + charlcd_4bit_print(lcd, 1, UTS_RELEASE); +} + +static void charlcd_init_work(struct work_struct *work) +{ + struct charlcd *lcd = + container_of(work, struct charlcd, init_work.work); + + charlcd_4bit_init(lcd); +} + +static int __init charlcd_probe(struct platform_device *pdev) +{ + int ret; + struct charlcd *lcd; + struct resource *res; + + lcd = kzalloc(sizeof(struct charlcd), GFP_KERNEL); + if (!lcd) + return -ENOMEM; + + lcd->dev = &pdev->dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENOENT; + goto out_no_resource; + } + lcd->phybase = res->start; + lcd->physize = resource_size(res); + + if (request_mem_region(lcd->phybase, lcd->physize, + DRIVERNAME) == NULL) { + ret = -EBUSY; + goto out_no_memregion; + } + + lcd->virtbase = ioremap(lcd->phybase, lcd->physize); + if (!lcd->virtbase) { + ret = -ENOMEM; + goto out_no_remap; + } + + lcd->irq = platform_get_irq(pdev, 0); + /* If no IRQ is supplied, we'll survive without it */ + if (lcd->irq >= 0) { + if (request_irq(lcd->irq, charlcd_interrupt, IRQF_DISABLED, + DRIVERNAME, lcd)) { + ret = -EIO; + goto out_no_irq; + } + } + + platform_set_drvdata(pdev, lcd); + + /* + * Initialize the display in a delayed work, because + * it is VERY slow and would slow down the boot of the system. + */ + INIT_DELAYED_WORK(&lcd->init_work, charlcd_init_work); + schedule_delayed_work(&lcd->init_work, 0); + + dev_info(&pdev->dev, "initalized ARM character LCD at %08x\n", + lcd->phybase); + + return 0; + +out_no_irq: + iounmap(lcd->virtbase); +out_no_remap: + platform_set_drvdata(pdev, NULL); +out_no_memregion: + release_mem_region(lcd->phybase, SZ_4K); +out_no_resource: + kfree(lcd); + return ret; +} + +static int __exit charlcd_remove(struct platform_device *pdev) +{ + struct charlcd *lcd = platform_get_drvdata(pdev); + + if (lcd) { + free_irq(lcd->irq, lcd); + iounmap(lcd->virtbase); + release_mem_region(lcd->phybase, lcd->physize); + platform_set_drvdata(pdev, NULL); + kfree(lcd); + } + + return 0; +} + +static int charlcd_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct charlcd *lcd = platform_get_drvdata(pdev); + + /* Power the display off */ + charlcd_4bit_command(lcd, HD_DISPCTRL); + return 0; +} + +static int charlcd_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct charlcd *lcd = platform_get_drvdata(pdev); + + /* Turn the display back on */ + charlcd_4bit_command(lcd, HD_DISPCTRL | HD_DISPCTRL_ON); + return 0; +} + +static const struct dev_pm_ops charlcd_pm_ops = { + .suspend = charlcd_suspend, + .resume = charlcd_resume, +}; + +static struct platform_driver charlcd_driver = { + .driver = { + .name = DRIVERNAME, + .owner = THIS_MODULE, + .pm = &charlcd_pm_ops, + }, + .remove = __exit_p(charlcd_remove), +}; + +static int __init charlcd_init(void) +{ + return platform_driver_probe(&charlcd_driver, charlcd_probe); +} + +static void __exit charlcd_exit(void) +{ + platform_driver_unregister(&charlcd_driver); +} + +module_init(charlcd_init); +module_exit(charlcd_exit); + +MODULE_AUTHOR("Linus Walleij <triad@df.lth.se>"); +MODULE_DESCRIPTION("ARM Character LCD Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c new file mode 100644 index 00000000000..714c6b48731 --- /dev/null +++ b/drivers/misc/bh1780gli.c @@ -0,0 +1,273 @@ +/* + * bh1780gli.c + * ROHM Ambient Light Sensor Driver + * + * Copyright (C) 2010 Texas Instruments + * Author: Hemanth V <hemanthv@ti.com> + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include <linux/i2c.h> +#include <linux/slab.h> +#include <linux/mutex.h> +#include <linux/platform_device.h> +#include <linux/delay.h> + +#define BH1780_REG_CONTROL 0x80 +#define BH1780_REG_PARTID 0x8A +#define BH1780_REG_MANFID 0x8B +#define BH1780_REG_DLOW 0x8C +#define BH1780_REG_DHIGH 0x8D + +#define BH1780_REVMASK (0xf) +#define BH1780_POWMASK (0x3) +#define BH1780_POFF (0x0) +#define BH1780_PON (0x3) + +/* power on settling time in ms */ +#define BH1780_PON_DELAY 2 + +struct bh1780_data { + struct i2c_client *client; + int power_state; + /* lock for sysfs operations */ + struct mutex lock; +}; + +static int bh1780_write(struct bh1780_data *ddata, u8 reg, u8 val, char *msg) +{ + int ret = i2c_smbus_write_byte_data(ddata->client, reg, val); + if (ret < 0) + dev_err(&ddata->client->dev, + "i2c_smbus_write_byte_data failed error %d\ + Register (%s)\n", ret, msg); + return ret; +} + +static int bh1780_read(struct bh1780_data *ddata, u8 reg, char *msg) +{ + int ret = i2c_smbus_read_byte_data(ddata->client, reg); + if (ret < 0) + dev_err(&ddata->client->dev, + "i2c_smbus_read_byte_data failed error %d\ + Register (%s)\n", ret, msg); + return ret; +} + +static ssize_t bh1780_show_lux(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bh1780_data *ddata = platform_get_drvdata(pdev); + int lsb, msb; + + lsb = bh1780_read(ddata, BH1780_REG_DLOW, "DLOW"); + if (lsb < 0) + return lsb; + + msb = bh1780_read(ddata, BH1780_REG_DHIGH, "DHIGH"); + if (msb < 0) + return msb; + + return sprintf(buf, "%d\n", (msb << 8) | lsb); +} + +static ssize_t bh1780_show_power_state(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bh1780_data *ddata = platform_get_drvdata(pdev); + int state; + + state = bh1780_read(ddata, BH1780_REG_CONTROL, "CONTROL"); + if (state < 0) + return state; + + return sprintf(buf, "%d\n", state & BH1780_POWMASK); +} + +static ssize_t bh1780_store_power_state(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct platform_device *pdev = to_platform_device(dev); + struct bh1780_data *ddata = platform_get_drvdata(pdev); + unsigned long val; + int error; + + error = strict_strtoul(buf, 0, &val); + if (error) + return error; + + if (val < BH1780_POFF || val > BH1780_PON) + return -EINVAL; + + mutex_lock(&ddata->lock); + + error = bh1780_write(ddata, BH1780_REG_CONTROL, val, "CONTROL"); + if (error < 0) { + mutex_unlock(&ddata->lock); + return error; + } + + msleep(BH1780_PON_DELAY); + ddata->power_state = val; + mutex_unlock(&ddata->lock); + + return count; +} + +static DEVICE_ATTR(lux, S_IRUGO, bh1780_show_lux, NULL); + +static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO, + bh1780_show_power_state, bh1780_store_power_state); + +static struct attribute *bh1780_attributes[] = { + &dev_attr_power_state.attr, + &dev_attr_lux.attr, + NULL +}; + +static const struct attribute_group bh1780_attr_group = { + .attrs = bh1780_attributes, +}; + +static int __devinit bh1780_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret; + struct bh1780_data *ddata = NULL; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) { + ret = -EIO; + goto err_op_failed; + } + + ddata = kzalloc(sizeof(struct bh1780_data), GFP_KERNEL); + if (ddata == NULL) { + ret = -ENOMEM; + goto err_op_failed; + } + + ddata->client = client; + i2c_set_clientdata(client, ddata); + + ret = bh1780_read(ddata, BH1780_REG_PARTID, "PART ID"); + if (ret < 0) + goto err_op_failed; + + dev_info(&client->dev, "Ambient Light Sensor, Rev : %d\n", + (ret & BH1780_REVMASK)); + + mutex_init(&ddata->lock); + + ret = sysfs_create_group(&client->dev.kobj, &bh1780_attr_group); + if (ret) + goto err_op_failed; + + return 0; + +err_op_failed: + kfree(ddata); + return ret; +} + +static int __devexit bh1780_remove(struct i2c_client *client) +{ + struct bh1780_data *ddata; + + ddata = i2c_get_clientdata(client); + sysfs_remove_group(&client->dev.kobj, &bh1780_attr_group); + i2c_set_clientdata(client, NULL); + kfree(ddata); + + return 0; +} + +#ifdef CONFIG_PM +static int bh1780_suspend(struct i2c_client *client, pm_message_t mesg) +{ + struct bh1780_data *ddata; + int state, ret; + + ddata = i2c_get_clientdata(client); + state = bh1780_read(ddata, BH1780_REG_CONTROL, "CONTROL"); + if (state < 0) + return state; + + ddata->power_state = state & BH1780_POWMASK; + + ret = bh1780_write(ddata, BH1780_REG_CONTROL, BH1780_POFF, + "CONTROL"); + + if (ret < 0) + return ret; + + return 0; +} + +static int bh1780_resume(struct i2c_client *client) +{ + struct bh1780_data *ddata; + int state, ret; + + ddata = i2c_get_clientdata(client); + state = ddata->power_state; + + ret = bh1780_write(ddata, BH1780_REG_CONTROL, state, + "CONTROL"); + + if (ret < 0) + return ret; + + return 0; +} +#else +#define bh1780_suspend NULL +#define bh1780_resume NULL +#endif /* CONFIG_PM */ + +static const struct i2c_device_id bh1780_id[] = { + { "bh1780", 0 }, + { }, +}; + +static struct i2c_driver bh1780_driver = { + .probe = bh1780_probe, + .remove = bh1780_remove, + .id_table = bh1780_id, + .suspend = bh1780_suspend, + .resume = bh1780_resume, + .driver = { + .name = "bh1780" + }, +}; + +static int __init bh1780_init(void) +{ + return i2c_add_driver(&bh1780_driver); +} + +static void __exit bh1780_exit(void) +{ + i2c_del_driver(&bh1780_driver); +} + +module_init(bh1780_init) +module_exit(bh1780_exit) + +MODULE_DESCRIPTION("BH1780GLI Ambient Light Sensor Driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>"); diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c new file mode 100644 index 00000000000..63ee4c1a531 --- /dev/null +++ b/drivers/misc/bmp085.c @@ -0,0 +1,482 @@ +/* Copyright (c) 2010 Christoph Mair <christoph.mair@gmail.com> + + This driver supports the bmp085 digital barometric pressure + and temperature sensor from Bosch Sensortec. The datasheet + is avaliable from their website: + http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf + + A pressure measurement is issued by reading from pressure0_input. + The return value ranges from 30000 to 110000 pascal with a resulution + of 1 pascal (0.01 millibar) which enables measurements from 9000m above + to 500m below sea level. + + The temperature can be read from temp0_input. Values range from + -400 to 850 representing the ambient temperature in degree celsius + multiplied by 10.The resolution is 0.1 celsius. + + Because ambient pressure is temperature dependent, a temperature + measurement will be executed automatically even if the user is reading + from pressure0_input. This happens if the last temperature measurement + has been executed more then one second ago. + + To decrease RMS noise from pressure measurements, the bmp085 can + autonomously calculate the average of up to eight samples. This is + set up by writing to the oversampling sysfs file. Accepted values + are 0, 1, 2 and 3. 2^x when x is the value written to this file + specifies the number of samples used to calculate the ambient pressure. + RMS noise is specified with six pascal (without averaging) and decreases + down to 3 pascal when using an oversampling setting of 3. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/i2c.h> +#include <linux/slab.h> +#include <linux/delay.h> + + +#define BMP085_I2C_ADDRESS 0x77 +#define BMP085_CHIP_ID 0x55 + +#define BMP085_CALIBRATION_DATA_START 0xAA +#define BMP085_CALIBRATION_DATA_LENGTH 11 /* 16 bit values */ +#define BMP085_CHIP_ID_REG 0xD0 +#define BMP085_VERSION_REG 0xD1 +#define BMP085_CTRL_REG 0xF4 +#define BMP085_TEMP_MEASUREMENT 0x2E +#define BMP085_PRESSURE_MEASUREMENT 0x34 +#define BMP085_CONVERSION_REGISTER_MSB 0xF6 +#define BMP085_CONVERSION_REGISTER_LSB 0xF7 +#define BMP085_CONVERSION_REGISTER_XLSB 0xF8 +#define BMP085_TEMP_CONVERSION_TIME 5 + +#define BMP085_CLIENT_NAME "bmp085" + + +static const unsigned short normal_i2c[] = { BMP085_I2C_ADDRESS, + I2C_CLIENT_END }; + +struct bmp085_calibration_data { + s16 AC1, AC2, AC3; + u16 AC4, AC5, AC6; + s16 B1, B2; + s16 MB, MC, MD; +}; + + +/* Each client has this additional data */ +struct bmp085_data { + struct i2c_client *client; + struct mutex lock; + struct bmp085_calibration_data calibration; + u32 raw_temperature; + u32 raw_pressure; + unsigned char oversampling_setting; + u32 last_temp_measurement; + s32 b6; /* calculated temperature correction coefficient */ +}; + + +static s32 bmp085_read_calibration_data(struct i2c_client *client) +{ + u16 tmp[BMP085_CALIBRATION_DATA_LENGTH]; + struct bmp085_data *data = i2c_get_clientdata(client); + struct bmp085_calibration_data *cali = &(data->calibration); + s32 status = i2c_smbus_read_i2c_block_data(client, + BMP085_CALIBRATION_DATA_START, + BMP085_CALIBRATION_DATA_LENGTH*sizeof(u16), + (u8 *)tmp); + if (status < 0) + return status; + + if (status != BMP085_CALIBRATION_DATA_LENGTH*sizeof(u16)) + return -EIO; + + cali->AC1 = be16_to_cpu(tmp[0]); + cali->AC2 = be16_to_cpu(tmp[1]); + cali->AC3 = be16_to_cpu(tmp[2]); + cali->AC4 = be16_to_cpu(tmp[3]); + cali->AC5 = be16_to_cpu(tmp[4]); + cali->AC6 = be16_to_cpu(tmp[5]); + cali->B1 = be16_to_cpu(tmp[6]); + cali->B2 = be16_to_cpu(tmp[7]); + cali->MB = be16_to_cpu(tmp[8]); + cali->MC = be16_to_cpu(tmp[9]); + cali->MD = be16_to_cpu(tmp[10]); + return 0; +} + + +static s32 bmp085_update_raw_temperature(struct bmp085_data *data) +{ + u16 tmp; + s32 status; + + mutex_lock(&data->lock); + status = i2c_smbus_write_byte_data(data->client, BMP085_CTRL_REG, + BMP085_TEMP_MEASUREMENT); + if (status != 0) { + dev_err(&data->client->dev, + "Error while requesting temperature measurement.\n"); + goto exit; + } + msleep(BMP085_TEMP_CONVERSION_TIME); + + status = i2c_smbus_read_i2c_block_data(data->client, + BMP085_CONVERSION_REGISTER_MSB, sizeof(tmp), (u8 *)&tmp); + if (status < 0) + goto exit; + if (status != sizeof(tmp)) { + dev_err(&data->client->dev, + "Error while reading temperature measurement result\n"); + status = -EIO; + goto exit; + } + data->raw_temperature = be16_to_cpu(tmp); + data->last_temp_measurement = jiffies; + status = 0; /* everything ok, return 0 */ + +exit: + mutex_unlock(&data->lock); + return status; +} + +static s32 bmp085_update_raw_pressure(struct bmp085_data *data) +{ + u32 tmp = 0; + s32 status; + + mutex_lock(&data->lock); + status = i2c_smbus_write_byte_data(data->client, BMP085_CTRL_REG, + BMP085_PRESSURE_MEASUREMENT + (data->oversampling_setting<<6)); + if (status != 0) { + dev_err(&data->client->dev, + "Error while requesting pressure measurement.\n"); + goto exit; + } + + /* wait for the end of conversion */ + msleep(2+(3 << data->oversampling_setting)); + + /* copy data into a u32 (4 bytes), but skip the first byte. */ + status = i2c_smbus_read_i2c_block_data(data->client, + BMP085_CONVERSION_REGISTER_MSB, 3, ((u8 *)&tmp)+1); + if (status < 0) + goto exit; + if (status != 3) { + dev_err(&data->client->dev, + "Error while reading pressure measurement results\n"); + status = -EIO; + goto exit; + } + data->raw_pressure = be32_to_cpu((tmp)); + data->raw_pressure >>= (8-data->oversampling_setting); + status = 0; /* everything ok, return 0 */ + +exit: + mutex_unlock(&data->lock); + return status; +} + + +/* + * This function starts the temperature measurement and returns the value + * in tenth of a degree celsius. + */ +static s32 bmp085_get_temperature(struct bmp085_data *data, int *temperature) +{ + struct bmp085_calibration_data *cali = &data->calibration; + long x1, x2; + int status; + + status = bmp085_update_raw_temperature(data); + if (status != 0) + goto exit; + + x1 = ((data->raw_temperature - cali->AC6) * cali->AC5) >> 15; + x2 = (cali->MC << 11) / (x1 + cali->MD); + data->b6 = x1 + x2 - 4000; + /* if NULL just update b6. Used for pressure only measurements */ + if (temperature != NULL) + *temperature = (x1+x2+8) >> 4; + +exit: + return status;; +} + +/* + * This function starts the pressure measurement and returns the value + * in millibar. Since the pressure depends on the ambient temperature, + * a temperature measurement is executed if the last known value is older + * than one second. + */ +static s32 bmp085_get_pressure(struct bmp085_data *data, int *pressure) +{ + struct bmp085_calibration_data *cali = &data->calibration; + s32 x1, x2, x3, b3; + u32 b4, b7; + s32 p; + int status; + + /* alt least every second force an update of the ambient temperature */ + if (data->last_temp_measurement + 1*HZ < jiffies) { + status = bmp085_get_temperature(data, NULL); + if (status != 0) + goto exit; + } + + status = bmp085_update_raw_pressure(data); + if (status != 0) + goto exit; + + x1 = (data->b6 * data->b6) >> 12; + x1 *= cali->B2; + x1 >>= 11; + + x2 = cali->AC2 * data->b6; + x2 >>= 11; + + x3 = x1 + x2; + + b3 = (((((s32)cali->AC1) * 4 + x3) << data->oversampling_setting) + 2); + b3 >>= 2; + + x1 = (cali->AC3 * data->b6) >> 13; + x2 = (cali->B1 * ((data->b6 * data->b6) >> 12)) >> 16; + x3 = (x1 + x2 + 2) >> 2; + b4 = (cali->AC4 * (u32)(x3 + 32768)) >> 15; + + b7 = ((u32)data->raw_pressure - b3) * + (50000 >> data->oversampling_setting); + p = ((b7 < 0x80000000) ? ((b7 << 1) / b4) : ((b7 / b4) * 2)); + + x1 = p >> 8; + x1 *= x1; + x1 = (x1 * 3038) >> 16; + x2 = (-7357 * p) >> 16; + p += (x1 + x2 + 3791) >> 4; + + *pressure = p; + +exit: + return status; +} + +/* + * This function sets the chip-internal oversampling. Valid values are 0..3. + * The chip will use 2^oversampling samples for internal averaging. + * This influences the measurement time and the accuracy; larger values + * increase both. The datasheet gives on overview on how measurement time, + * accuracy and noise correlate. + */ +static void bmp085_set_oversampling(struct bmp085_data *data, + unsigned char oversampling) +{ + if (oversampling > 3) + oversampling = 3; + data->oversampling_setting = oversampling; +} + +/* + * Returns the currently selected oversampling. Range: 0..3 + */ +static unsigned char bmp085_get_oversampling(struct bmp085_data *data) +{ + return data->oversampling_setting; +} + +/* sysfs callbacks */ +static ssize_t set_oversampling(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bmp085_data *data = i2c_get_clientdata(client); + unsigned long oversampling; + int success = strict_strtoul(buf, 10, &oversampling); + if (success == 0) { + bmp085_set_oversampling(data, oversampling); + return count; + } + return success; +} + +static ssize_t show_oversampling(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct bmp085_data *data = i2c_get_clientdata(client); + return sprintf(buf, "%u\n", bmp085_get_oversampling(data)); +} +static DEVICE_ATTR(oversampling, S_IWUSR | S_IRUGO, + show_oversampling, set_oversampling); + + +static ssize_t show_temperature(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int temperature; + int status; + struct i2c_client *client = to_i2c_client(dev); + struct bmp085_data *data = i2c_get_clientdata(client); + + status = bmp085_get_temperature(data, &temperature); + if (status != 0) + return status; + else + return sprintf(buf, "%d\n", temperature); +} +static DEVICE_ATTR(temp0_input, S_IRUGO, show_temperature, NULL); + + +static ssize_t show_pressure(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int pressure; + int status; + struct i2c_client *client = to_i2c_client(dev); + struct bmp085_data *data = i2c_get_clientdata(client); + + status = bmp085_get_pressure(data, &pressure); + if (status != 0) + return status; + else + return sprintf(buf, "%d\n", pressure); +} +static DEVICE_ATTR(pressure0_input, S_IRUGO, show_pressure, NULL); + + +static struct attribute *bmp085_attributes[] = { + &dev_attr_temp0_input.attr, + &dev_attr_pressure0_input.attr, + &dev_attr_oversampling.attr, + NULL +}; + +static const struct attribute_group bmp085_attr_group = { + .attrs = bmp085_attributes, +}; + +static int bmp085_detect(struct i2c_client *client, struct i2c_board_info *info) +{ + if (client->addr != BMP085_I2C_ADDRESS) + return -ENODEV; + + if (i2c_smbus_read_byte_data(client, BMP085_CHIP_ID_REG) != BMP085_CHIP_ID) + return -ENODEV; + + return 0; +} + +static int bmp085_init_client(struct i2c_client *client) +{ + unsigned char version; + int status; + struct bmp085_data *data = i2c_get_clientdata(client); + data->client = client; + status = bmp085_read_calibration_data(client); + if (status != 0) + goto exit; + version = i2c_smbus_read_byte_data(client, BMP085_VERSION_REG); + data->last_temp_measurement = 0; + data->oversampling_setting = 3; + mutex_init(&data->lock); + dev_info(&data->client->dev, "BMP085 ver. %d.%d found.\n", + (version & 0x0F), (version & 0xF0) >> 4); +exit: + return status; +} + +static int bmp085_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct bmp085_data *data; + int err = 0; + + data = kzalloc(sizeof(struct bmp085_data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + /* default settings after POR */ + data->oversampling_setting = 0x00; + + i2c_set_clientdata(client, data); + + /* Initialize the BMP085 chip */ + err = bmp085_init_client(client); + if (err != 0) + goto exit_free; + + /* Register sysfs hooks */ + err = sysfs_create_group(&client->dev.kobj, &bmp085_attr_group); + if (err) + goto exit_free; + + dev_info(&data->client->dev, "Succesfully initialized bmp085!\n"); + goto exit; + +exit_free: + kfree(data); +exit: + return err; +} + +static int bmp085_remove(struct i2c_client *client) +{ + sysfs_remove_group(&client->dev.kobj, &bmp085_attr_group); + kfree(i2c_get_clientdata(client)); + return 0; +} + +static const struct i2c_device_id bmp085_id[] = { + { "bmp085", 0 }, + { } +}; + +static struct i2c_driver bmp085_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "bmp085" + }, + .id_table = bmp085_id, + .probe = bmp085_probe, + .remove = bmp085_remove, + + .detect = bmp085_detect, + .address_list = normal_i2c +}; + +static int __init bmp085_init(void) +{ + return i2c_add_driver(&bmp085_driver); +} + +static void __exit bmp085_exit(void) +{ + i2c_del_driver(&bmp085_driver); +} + + +MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com"); +MODULE_DESCRIPTION("BMP085 driver"); +MODULE_LICENSE("GPL"); + +module_init(bmp085_init); +module_exit(bmp085_exit); diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c index 2d44b330010..6f6218061b0 100644 --- a/drivers/misc/cs5535-mfgpt.c +++ b/drivers/misc/cs5535-mfgpt.c @@ -211,6 +211,17 @@ EXPORT_SYMBOL_GPL(cs5535_mfgpt_alloc_timer); */ void cs5535_mfgpt_free_timer(struct cs5535_mfgpt_timer *timer) { + unsigned long flags; + uint16_t val; + + /* timer can be made available again only if never set up */ + val = cs5535_mfgpt_read(timer, MFGPT_REG_SETUP); + if (!(val & MFGPT_SETUP_SETUP)) { + spin_lock_irqsave(&timer->chip->lock, flags); + __set_bit(timer->nr, timer->chip->avail); + spin_unlock_irqrestore(&timer->chip->lock, flags); + } + kfree(timer); } EXPORT_SYMBOL_GPL(cs5535_mfgpt_free_timer); diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index 48c84a58163..00e5fcac8fd 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c @@ -285,8 +285,11 @@ enclosure_component_register(struct enclosure_device *edev, cdev->groups = enclosure_groups; err = device_register(cdev); - if (err) - ERR_PTR(err); + if (err) { + ecomp->number = -1; + put_device(cdev); + return ERR_PTR(err); + } return ecomp; } diff --git a/drivers/misc/hmc6352.c b/drivers/misc/hmc6352.c new file mode 100644 index 00000000000..234bfcaf209 --- /dev/null +++ b/drivers/misc/hmc6352.c @@ -0,0 +1,166 @@ +/* + * hmc6352.c - Honeywell Compass Driver + * + * Copyright (C) 2009 Intel Corp + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/i2c.h> +#include <linux/err.h> +#include <linux/delay.h> +#include <linux/sysfs.h> + +static DEFINE_MUTEX(compass_mutex); + +static int compass_command(struct i2c_client *c, u8 cmd) +{ + int ret = i2c_master_send(c, &cmd, 1); + if (ret < 0) + dev_warn(&c->dev, "command '%c' failed.\n", cmd); + return ret; +} + +static int compass_store(struct device *dev, const char *buf, size_t count, + const char *map) +{ + struct i2c_client *c = to_i2c_client(dev); + int ret; + unsigned long val; + + if (strict_strtoul(buf, 10, &val)) + return -EINVAL; + if (val >= strlen(map)) + return -EINVAL; + mutex_lock(&compass_mutex); + ret = compass_command(c, map[val]); + mutex_unlock(&compass_mutex); + if (ret < 0) + return ret; + return count; +} + +static ssize_t compass_calibration_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + return compass_store(dev, buf, count, "EC"); +} + +static ssize_t compass_power_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + return compass_store(dev, buf, count, "SW"); +} + +static ssize_t compass_heading_data_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + unsigned char i2c_data[2]; + unsigned int ret; + + mutex_lock(&compass_mutex); + ret = compass_command(client, 'A'); + if (ret != 1) { + mutex_unlock(&compass_mutex); + return ret; + } + msleep(10); /* sending 'A' cmd we need to wait for 7-10 millisecs */ + ret = i2c_master_recv(client, i2c_data, 2); + mutex_unlock(&compass_mutex); + if (ret != 1) { + dev_warn(dev, "i2c read data cmd failed\n"); + return ret; + } + ret = (i2c_data[0] << 8) | i2c_data[1]; + return sprintf(buf, "%d.%d\n", ret/10, ret%10); +} + + +static DEVICE_ATTR(heading0_input, S_IRUGO, compass_heading_data_show, NULL); +static DEVICE_ATTR(calibration, S_IWUSR, NULL, compass_calibration_store); +static DEVICE_ATTR(power_state, S_IWUSR, NULL, compass_power_mode_store); + +static struct attribute *mid_att_compass[] = { + &dev_attr_heading0_input.attr, + &dev_attr_calibration.attr, + &dev_attr_power_state.attr, + NULL +}; + +static const struct attribute_group m_compass_gr = { + .name = "hmc6352", + .attrs = mid_att_compass +}; + +static int hmc6352_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int res; + + res = sysfs_create_group(&client->dev.kobj, &m_compass_gr); + if (res) { + dev_err(&client->dev, "device_create_file failed\n"); + return res; + } + dev_info(&client->dev, "%s HMC6352 compass chip found\n", + client->name); + return 0; +} + +static int hmc6352_remove(struct i2c_client *client) +{ + sysfs_remove_group(&client->dev.kobj, &m_compass_gr); + return 0; +} + +static struct i2c_device_id hmc6352_id[] = { + { "hmc6352", 0 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, hmc6352_id); + +static struct i2c_driver hmc6352_driver = { + .driver = { + .name = "hmc6352", + }, + .probe = hmc6352_probe, + .remove = hmc6352_remove, + .id_table = hmc6352_id, +}; + +static int __init sensor_hmc6352_init(void) +{ + return i2c_add_driver(&hmc6352_driver); +} + +static void __exit sensor_hmc6352_exit(void) +{ + i2c_del_driver(&hmc6352_driver); +} + +module_init(sensor_hmc6352_init); +module_exit(sensor_hmc6352_exit); + +MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com"); +MODULE_DESCRIPTION("hmc6352 Compass Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index 98ad0120aa9..557a8c2a733 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -256,7 +256,8 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data) static int ilo_ccb_setup(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) { - char *dma_va, *dma_pa; + char *dma_va; + dma_addr_t dma_pa; struct ccb *driver_ccb, *ilo_ccb; driver_ccb = &data->driver_ccb; @@ -272,12 +273,12 @@ static int ilo_ccb_setup(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) return -ENOMEM; dma_va = (char *)data->dma_va; - dma_pa = (char *)data->dma_pa; + dma_pa = data->dma_pa; memset(dma_va, 0, data->dma_size); dma_va = (char *)roundup((unsigned long)dma_va, ILO_START_ALIGN); - dma_pa = (char *)roundup((unsigned long)dma_pa, ILO_START_ALIGN); + dma_pa = roundup(dma_pa, ILO_START_ALIGN); /* * Create two ccb's, one with virt addrs, one with phys addrs. @@ -288,26 +289,26 @@ static int ilo_ccb_setup(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) fifo_setup(dma_va, NR_QENTRY); driver_ccb->ccb_u1.send_fifobar = dma_va + FIFOHANDLESIZE; - ilo_ccb->ccb_u1.send_fifobar = dma_pa + FIFOHANDLESIZE; + ilo_ccb->ccb_u1.send_fifobar_pa = dma_pa + FIFOHANDLESIZE; dma_va += fifo_sz(NR_QENTRY); dma_pa += fifo_sz(NR_QENTRY); dma_va = (char *)roundup((unsigned long)dma_va, ILO_CACHE_SZ); - dma_pa = (char *)roundup((unsigned long)dma_pa, ILO_CACHE_SZ); + dma_pa = roundup(dma_pa, ILO_CACHE_SZ); fifo_setup(dma_va, NR_QENTRY); driver_ccb->ccb_u3.recv_fifobar = dma_va + FIFOHANDLESIZE; - ilo_ccb->ccb_u3.recv_fifobar = dma_pa + FIFOHANDLESIZE; + ilo_ccb->ccb_u3.recv_fifobar_pa = dma_pa + FIFOHANDLESIZE; dma_va += fifo_sz(NR_QENTRY); dma_pa += fifo_sz(NR_QENTRY); driver_ccb->ccb_u2.send_desc = dma_va; - ilo_ccb->ccb_u2.send_desc = dma_pa; + ilo_ccb->ccb_u2.send_desc_pa = dma_pa; dma_pa += desc_mem_sz(NR_QENTRY); dma_va += desc_mem_sz(NR_QENTRY); driver_ccb->ccb_u4.recv_desc = dma_va; - ilo_ccb->ccb_u4.recv_desc = dma_pa; + ilo_ccb->ccb_u4.recv_desc_pa = dma_pa; driver_ccb->channel = slot; ilo_ccb->channel = slot; diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h index 247eb386a97..54e43adbdea 100644 --- a/drivers/misc/hpilo.h +++ b/drivers/misc/hpilo.h @@ -79,21 +79,21 @@ struct ilo_hwinfo { struct ccb { union { char *send_fifobar; - u64 padding1; + u64 send_fifobar_pa; } ccb_u1; union { char *send_desc; - u64 padding2; + u64 send_desc_pa; } ccb_u2; u64 send_ctrl; union { char *recv_fifobar; - u64 padding3; + u64 recv_fifobar_pa; } ccb_u3; union { char *recv_desc; - u64 padding4; + u64 recv_desc_pa; } ccb_u4; u64 recv_ctrl; diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index 5bfb2a2041b..ef34de7a802 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c @@ -124,9 +124,9 @@ static int count = DEFAULT_COUNT; module_param(recur_count, int, 0644); MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ "default is 10"); -module_param(cpoint_name, charp, 0644); +module_param(cpoint_name, charp, 0444); MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed"); -module_param(cpoint_type, charp, 0644); +module_param(cpoint_type, charp, 0444); MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\ "hitting the crash point"); module_param(cpoint_count, int, 0644); |