diff options
Diffstat (limited to 'drivers/misc')
| -rw-r--r-- | drivers/misc/Kconfig | 13 | ||||
| -rw-r--r-- | drivers/misc/Makefile | 1 | ||||
| -rw-r--r-- | drivers/misc/eeprom/at25.c | 2 | ||||
| -rw-r--r-- | drivers/misc/eeprom/max6875.c | 29 | ||||
| -rw-r--r-- | drivers/misc/enclosure.c | 73 | ||||
| -rw-r--r-- | drivers/misc/ep93xx_pwm.c | 384 | ||||
| -rw-r--r-- | drivers/misc/hpilo.c | 291 | ||||
| -rw-r--r-- | drivers/misc/hpilo.h | 8 | ||||
| -rw-r--r-- | drivers/misc/ibmasm/command.c | 1 | ||||
| -rw-r--r-- | drivers/misc/ibmasm/event.c | 1 | ||||
| -rw-r--r-- | drivers/misc/ibmasm/ibmasmfs.c | 2 | ||||
| -rw-r--r-- | drivers/misc/ibmasm/r_heartbeat.c | 1 | ||||
| -rw-r--r-- | drivers/misc/lkdtm.c | 2 | ||||
| -rw-r--r-- | drivers/misc/phantom.c | 3 | ||||
| -rw-r--r-- | drivers/misc/sgi-gru/grufile.c | 5 | ||||
| -rw-r--r-- | drivers/misc/sgi-gru/grukservices.c | 2 | ||||
| -rw-r--r-- | drivers/misc/sgi-gru/gruprocfs.c | 3 | ||||
| -rw-r--r-- | drivers/misc/sgi-gru/grutables.h | 2 | ||||
| -rw-r--r-- | drivers/misc/sgi-xp/xpc_sn2.c | 40 | ||||
| -rw-r--r-- | drivers/misc/sgi-xp/xpnet.c | 5 |
20 files changed, 702 insertions, 166 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 68ab39d7cb35..df1f86b5c83e 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
| @@ -233,6 +233,19 @@ config ISL29003 | |||
| 233 | This driver can also be built as a module. If so, the module | 233 | This driver can also be built as a module. If so, the module |
| 234 | will be called isl29003. | 234 | will be called isl29003. |
| 235 | 235 | ||
| 236 | config EP93XX_PWM | ||
| 237 | tristate "EP93xx PWM support" | ||
| 238 | depends on ARCH_EP93XX | ||
| 239 | help | ||
| 240 | This option enables device driver support for the PWM channels | ||
| 241 | on the Cirrus EP93xx processors. The EP9307 chip only has one | ||
| 242 | PWM channel all the others have two, the second channel is an | ||
| 243 | alternate function of the EGPIO14 pin. A sysfs interface is | ||
| 244 | provided to control the PWM channels. | ||
| 245 | |||
| 246 | To compile this driver as a module, choose M here: the module will | ||
| 247 | be called ep93xx_pwm. | ||
| 248 | |||
| 236 | source "drivers/misc/c2port/Kconfig" | 249 | source "drivers/misc/c2port/Kconfig" |
| 237 | source "drivers/misc/eeprom/Kconfig" | 250 | source "drivers/misc/eeprom/Kconfig" |
| 238 | source "drivers/misc/cb710/Kconfig" | 251 | source "drivers/misc/cb710/Kconfig" |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 36f733cd60e6..f982d2ecfde7 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
| @@ -19,6 +19,7 @@ obj-$(CONFIG_SGI_XP) += sgi-xp/ | |||
| 19 | obj-$(CONFIG_SGI_GRU) += sgi-gru/ | 19 | obj-$(CONFIG_SGI_GRU) += sgi-gru/ |
| 20 | obj-$(CONFIG_HP_ILO) += hpilo.o | 20 | obj-$(CONFIG_HP_ILO) += hpilo.o |
| 21 | obj-$(CONFIG_ISL29003) += isl29003.o | 21 | obj-$(CONFIG_ISL29003) += isl29003.o |
| 22 | obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o | ||
| 22 | obj-$(CONFIG_C2PORT) += c2port/ | 23 | obj-$(CONFIG_C2PORT) += c2port/ |
| 23 | obj-y += eeprom/ | 24 | obj-y += eeprom/ |
| 24 | obj-y += cb710/ | 25 | obj-y += cb710/ |
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 2e535a0ccd5e..d902d81dde39 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c | |||
| @@ -417,4 +417,4 @@ module_exit(at25_exit); | |||
| 417 | MODULE_DESCRIPTION("Driver for most SPI EEPROMs"); | 417 | MODULE_DESCRIPTION("Driver for most SPI EEPROMs"); |
| 418 | MODULE_AUTHOR("David Brownell"); | 418 | MODULE_AUTHOR("David Brownell"); |
| 419 | MODULE_LICENSE("GPL"); | 419 | MODULE_LICENSE("GPL"); |
| 420 | 420 | MODULE_ALIAS("spi:at25"); | |
diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c index 3c0c58eed347..5a6b2bce8ad5 100644 --- a/drivers/misc/eeprom/max6875.c +++ b/drivers/misc/eeprom/max6875.c | |||
| @@ -33,12 +33,6 @@ | |||
| 33 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
| 34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
| 35 | 35 | ||
| 36 | /* Do not scan - the MAX6875 access method will write to some EEPROM chips */ | ||
| 37 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; | ||
| 38 | |||
| 39 | /* Insmod parameters */ | ||
| 40 | I2C_CLIENT_INSMOD_1(max6875); | ||
| 41 | |||
| 42 | /* The MAX6875 can only read/write 16 bytes at a time */ | 36 | /* The MAX6875 can only read/write 16 bytes at a time */ |
| 43 | #define SLICE_SIZE 16 | 37 | #define SLICE_SIZE 16 |
| 44 | #define SLICE_BITS 4 | 38 | #define SLICE_BITS 4 |
| @@ -146,31 +140,21 @@ static struct bin_attribute user_eeprom_attr = { | |||
| 146 | .read = max6875_read, | 140 | .read = max6875_read, |
| 147 | }; | 141 | }; |
| 148 | 142 | ||
| 149 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 143 | static int max6875_probe(struct i2c_client *client, |
| 150 | static int max6875_detect(struct i2c_client *client, int kind, | 144 | const struct i2c_device_id *id) |
| 151 | struct i2c_board_info *info) | ||
| 152 | { | 145 | { |
| 153 | struct i2c_adapter *adapter = client->adapter; | 146 | struct i2c_adapter *adapter = client->adapter; |
| 147 | struct max6875_data *data; | ||
| 148 | int err; | ||
| 154 | 149 | ||
| 155 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA | 150 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
| 156 | | I2C_FUNC_SMBUS_READ_BYTE)) | 151 | | I2C_FUNC_SMBUS_READ_BYTE)) |
| 157 | return -ENODEV; | 152 | return -ENODEV; |
| 158 | 153 | ||
| 159 | /* Only check even addresses */ | 154 | /* Only bind to even addresses */ |
| 160 | if (client->addr & 1) | 155 | if (client->addr & 1) |
| 161 | return -ENODEV; | 156 | return -ENODEV; |
| 162 | 157 | ||
| 163 | strlcpy(info->type, "max6875", I2C_NAME_SIZE); | ||
| 164 | |||
| 165 | return 0; | ||
| 166 | } | ||
| 167 | |||
| 168 | static int max6875_probe(struct i2c_client *client, | ||
| 169 | const struct i2c_device_id *id) | ||
| 170 | { | ||
| 171 | struct max6875_data *data; | ||
| 172 | int err; | ||
| 173 | |||
| 174 | if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL))) | 158 | if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL))) |
| 175 | return -ENOMEM; | 159 | return -ENOMEM; |
| 176 | 160 | ||
| @@ -222,9 +206,6 @@ static struct i2c_driver max6875_driver = { | |||
| 222 | .probe = max6875_probe, | 206 | .probe = max6875_probe, |
| 223 | .remove = max6875_remove, | 207 | .remove = max6875_remove, |
| 224 | .id_table = max6875_id, | 208 | .id_table = max6875_id, |
| 225 | |||
| 226 | .detect = max6875_detect, | ||
| 227 | .address_data = &addr_data, | ||
| 228 | }; | 209 | }; |
| 229 | 210 | ||
| 230 | static int __init max6875_init(void) | 211 | static int __init max6875_init(void) |
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index 348443bdb23b..e9eae4a78402 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c | |||
| @@ -33,24 +33,44 @@ static DEFINE_MUTEX(container_list_lock); | |||
| 33 | static struct class enclosure_class; | 33 | static struct class enclosure_class; |
| 34 | 34 | ||
| 35 | /** | 35 | /** |
| 36 | * enclosure_find - find an enclosure given a device | 36 | * enclosure_find - find an enclosure given a parent device |
| 37 | * @dev: the device to find for | 37 | * @dev: the parent to match against |
| 38 | * @start: Optional enclosure device to start from (NULL if none) | ||
| 38 | * | 39 | * |
| 39 | * Looks through the list of registered enclosures to see | 40 | * Looks through the list of registered enclosures to find all those |
| 40 | * if it can find a match for a device. Returns NULL if no | 41 | * with @dev as a parent. Returns NULL if no enclosure is |
| 41 | * enclosure is found. Obtains a reference to the enclosure class | 42 | * found. @start can be used as a starting point to obtain multiple |
| 42 | * device which must be released with device_put(). | 43 | * enclosures per parent (should begin with NULL and then be set to |
| 44 | * each returned enclosure device). Obtains a reference to the | ||
| 45 | * enclosure class device which must be released with device_put(). | ||
| 46 | * If @start is not NULL, a reference must be taken on it which is | ||
| 47 | * released before returning (this allows a loop through all | ||
| 48 | * enclosures to exit with only the reference on the enclosure of | ||
| 49 | * interest held). Note that the @dev may correspond to the actual | ||
| 50 | * device housing the enclosure, in which case no iteration via @start | ||
| 51 | * is required. | ||
| 43 | */ | 52 | */ |
| 44 | struct enclosure_device *enclosure_find(struct device *dev) | 53 | struct enclosure_device *enclosure_find(struct device *dev, |
| 54 | struct enclosure_device *start) | ||
| 45 | { | 55 | { |
| 46 | struct enclosure_device *edev; | 56 | struct enclosure_device *edev; |
| 47 | 57 | ||
| 48 | mutex_lock(&container_list_lock); | 58 | mutex_lock(&container_list_lock); |
| 49 | list_for_each_entry(edev, &container_list, node) { | 59 | edev = list_prepare_entry(start, &container_list, node); |
| 50 | if (edev->edev.parent == dev) { | 60 | if (start) |
| 51 | get_device(&edev->edev); | 61 | put_device(&start->edev); |
| 52 | mutex_unlock(&container_list_lock); | 62 | |
| 53 | return edev; | 63 | list_for_each_entry_continue(edev, &container_list, node) { |
| 64 | struct device *parent = edev->edev.parent; | ||
| 65 | /* parent might not be immediate, so iterate up to | ||
| 66 | * the root of the tree if necessary */ | ||
| 67 | while (parent) { | ||
| 68 | if (parent == dev) { | ||
| 69 | get_device(&edev->edev); | ||
| 70 | mutex_unlock(&container_list_lock); | ||
| 71 | return edev; | ||
| 72 | } | ||
| 73 | parent = parent->parent; | ||
| 54 | } | 74 | } |
| 55 | } | 75 | } |
| 56 | mutex_unlock(&container_list_lock); | 76 | mutex_unlock(&container_list_lock); |
| @@ -218,7 +238,7 @@ static void enclosure_component_release(struct device *dev) | |||
| 218 | put_device(dev->parent); | 238 | put_device(dev->parent); |
| 219 | } | 239 | } |
| 220 | 240 | ||
| 221 | static struct attribute_group *enclosure_groups[]; | 241 | static const struct attribute_group *enclosure_groups[]; |
| 222 | 242 | ||
| 223 | /** | 243 | /** |
| 224 | * enclosure_component_register - add a particular component to an enclosure | 244 | * enclosure_component_register - add a particular component to an enclosure |
| @@ -295,6 +315,9 @@ int enclosure_add_device(struct enclosure_device *edev, int component, | |||
| 295 | 315 | ||
| 296 | cdev = &edev->component[component]; | 316 | cdev = &edev->component[component]; |
| 297 | 317 | ||
| 318 | if (cdev->dev == dev) | ||
| 319 | return -EEXIST; | ||
| 320 | |||
| 298 | if (cdev->dev) | 321 | if (cdev->dev) |
| 299 | enclosure_remove_links(cdev); | 322 | enclosure_remove_links(cdev); |
| 300 | 323 | ||
| @@ -312,19 +335,25 @@ EXPORT_SYMBOL_GPL(enclosure_add_device); | |||
| 312 | * Returns zero on success or an error. | 335 | * Returns zero on success or an error. |
| 313 | * | 336 | * |
| 314 | */ | 337 | */ |
| 315 | int enclosure_remove_device(struct enclosure_device *edev, int component) | 338 | int enclosure_remove_device(struct enclosure_device *edev, struct device *dev) |
| 316 | { | 339 | { |
| 317 | struct enclosure_component *cdev; | 340 | struct enclosure_component *cdev; |
| 341 | int i; | ||
| 318 | 342 | ||
| 319 | if (!edev || component >= edev->components) | 343 | if (!edev || !dev) |
| 320 | return -EINVAL; | 344 | return -EINVAL; |
| 321 | 345 | ||
| 322 | cdev = &edev->component[component]; | 346 | for (i = 0; i < edev->components; i++) { |
| 323 | 347 | cdev = &edev->component[i]; | |
| 324 | device_del(&cdev->cdev); | 348 | if (cdev->dev == dev) { |
| 325 | put_device(cdev->dev); | 349 | enclosure_remove_links(cdev); |
| 326 | cdev->dev = NULL; | 350 | device_del(&cdev->cdev); |
| 327 | return device_add(&cdev->cdev); | 351 | put_device(dev); |
| 352 | cdev->dev = NULL; | ||
| 353 | return device_add(&cdev->cdev); | ||
| 354 | } | ||
| 355 | } | ||
| 356 | return -ENODEV; | ||
| 328 | } | 357 | } |
| 329 | EXPORT_SYMBOL_GPL(enclosure_remove_device); | 358 | EXPORT_SYMBOL_GPL(enclosure_remove_device); |
| 330 | 359 | ||
| @@ -507,7 +536,7 @@ static struct attribute_group enclosure_group = { | |||
| 507 | .attrs = enclosure_component_attrs, | 536 | .attrs = enclosure_component_attrs, |
| 508 | }; | 537 | }; |
| 509 | 538 | ||
| 510 | static struct attribute_group *enclosure_groups[] = { | 539 | static const struct attribute_group *enclosure_groups[] = { |
| 511 | &enclosure_group, | 540 | &enclosure_group, |
| 512 | NULL | 541 | NULL |
| 513 | }; | 542 | }; |
diff --git a/drivers/misc/ep93xx_pwm.c b/drivers/misc/ep93xx_pwm.c new file mode 100644 index 000000000000..ba4694169d79 --- /dev/null +++ b/drivers/misc/ep93xx_pwm.c | |||
| @@ -0,0 +1,384 @@ | |||
| 1 | /* | ||
| 2 | * Simple PWM driver for EP93XX | ||
| 3 | * | ||
| 4 | * (c) Copyright 2009 Matthieu Crapet <mcrapet@gmail.com> | ||
| 5 | * (c) Copyright 2009 H Hartley Sweeten <hsweeten@visionengravers.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version | ||
| 10 | * 2 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | * EP9307 has only one channel: | ||
| 13 | * - PWMOUT | ||
| 14 | * | ||
| 15 | * EP9301/02/12/15 have two channels: | ||
| 16 | * - PWMOUT | ||
| 17 | * - PWMOUT1 (alternate function for EGPIO14) | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/platform_device.h> | ||
| 22 | #include <linux/clk.h> | ||
| 23 | #include <linux/err.h> | ||
| 24 | #include <linux/io.h> | ||
| 25 | |||
| 26 | #include <mach/platform.h> | ||
| 27 | |||
| 28 | #define EP93XX_PWMx_TERM_COUNT 0x00 | ||
| 29 | #define EP93XX_PWMx_DUTY_CYCLE 0x04 | ||
| 30 | #define EP93XX_PWMx_ENABLE 0x08 | ||
| 31 | #define EP93XX_PWMx_INVERT 0x0C | ||
| 32 | |||
| 33 | #define EP93XX_PWM_MAX_COUNT 0xFFFF | ||
| 34 | |||
| 35 | struct ep93xx_pwm { | ||
| 36 | void __iomem *mmio_base; | ||
| 37 | struct clk *clk; | ||
| 38 | u32 duty_percent; | ||
| 39 | }; | ||
| 40 | |||
| 41 | static inline void ep93xx_pwm_writel(struct ep93xx_pwm *pwm, | ||
| 42 | unsigned int val, unsigned int off) | ||
| 43 | { | ||
| 44 | __raw_writel(val, pwm->mmio_base + off); | ||
| 45 | } | ||
| 46 | |||
| 47 | static inline unsigned int ep93xx_pwm_readl(struct ep93xx_pwm *pwm, | ||
| 48 | unsigned int off) | ||
| 49 | { | ||
| 50 | return __raw_readl(pwm->mmio_base + off); | ||
| 51 | } | ||
| 52 | |||
| 53 | static inline void ep93xx_pwm_write_tc(struct ep93xx_pwm *pwm, u16 value) | ||
| 54 | { | ||
| 55 | ep93xx_pwm_writel(pwm, value, EP93XX_PWMx_TERM_COUNT); | ||
| 56 | } | ||
| 57 | |||
| 58 | static inline u16 ep93xx_pwm_read_tc(struct ep93xx_pwm *pwm) | ||
| 59 | { | ||
| 60 | return ep93xx_pwm_readl(pwm, EP93XX_PWMx_TERM_COUNT); | ||
| 61 | } | ||
| 62 | |||
| 63 | static inline void ep93xx_pwm_write_dc(struct ep93xx_pwm *pwm, u16 value) | ||
| 64 | { | ||
| 65 | ep93xx_pwm_writel(pwm, value, EP93XX_PWMx_DUTY_CYCLE); | ||
| 66 | } | ||
| 67 | |||
| 68 | static inline void ep93xx_pwm_enable(struct ep93xx_pwm *pwm) | ||
| 69 | { | ||
| 70 | ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_ENABLE); | ||
| 71 | } | ||
| 72 | |||
| 73 | static inline void ep93xx_pwm_disable(struct ep93xx_pwm *pwm) | ||
| 74 | { | ||
| 75 | ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_ENABLE); | ||
| 76 | } | ||
| 77 | |||
| 78 | static inline int ep93xx_pwm_is_enabled(struct ep93xx_pwm *pwm) | ||
| 79 | { | ||
| 80 | return ep93xx_pwm_readl(pwm, EP93XX_PWMx_ENABLE) & 0x1; | ||
| 81 | } | ||
| 82 | |||
| 83 | static inline void ep93xx_pwm_invert(struct ep93xx_pwm *pwm) | ||
| 84 | { | ||
| 85 | ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_INVERT); | ||
| 86 | } | ||
| 87 | |||
| 88 | static inline void ep93xx_pwm_normal(struct ep93xx_pwm *pwm) | ||
| 89 | { | ||
| 90 | ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_INVERT); | ||
| 91 | } | ||
| 92 | |||
| 93 | static inline int ep93xx_pwm_is_inverted(struct ep93xx_pwm *pwm) | ||
| 94 | { | ||
| 95 | return ep93xx_pwm_readl(pwm, EP93XX_PWMx_INVERT) & 0x1; | ||
| 96 | } | ||
| 97 | |||
| 98 | /* | ||
| 99 | * /sys/devices/platform/ep93xx-pwm.N | ||
| 100 | * /min_freq read-only minimum pwm output frequency | ||
| 101 | * /max_req read-only maximum pwm output frequency | ||
| 102 | * /freq read-write pwm output frequency (0 = disable output) | ||
| 103 | * /duty_percent read-write pwm duty cycle percent (1..99) | ||
| 104 | * /invert read-write invert pwm output | ||
| 105 | */ | ||
| 106 | |||
| 107 | static ssize_t ep93xx_pwm_get_min_freq(struct device *dev, | ||
| 108 | struct device_attribute *attr, char *buf) | ||
| 109 | { | ||
| 110 | struct platform_device *pdev = to_platform_device(dev); | ||
| 111 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
| 112 | unsigned long rate = clk_get_rate(pwm->clk); | ||
| 113 | |||
| 114 | return sprintf(buf, "%ld\n", rate / (EP93XX_PWM_MAX_COUNT + 1)); | ||
| 115 | } | ||
| 116 | |||
| 117 | static ssize_t ep93xx_pwm_get_max_freq(struct device *dev, | ||
| 118 | struct device_attribute *attr, char *buf) | ||
| 119 | { | ||
| 120 | struct platform_device *pdev = to_platform_device(dev); | ||
| 121 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
| 122 | unsigned long rate = clk_get_rate(pwm->clk); | ||
| 123 | |||
| 124 | return sprintf(buf, "%ld\n", rate / 2); | ||
| 125 | } | ||
| 126 | |||
| 127 | static ssize_t ep93xx_pwm_get_freq(struct device *dev, | ||
| 128 | struct device_attribute *attr, char *buf) | ||
| 129 | { | ||
| 130 | struct platform_device *pdev = to_platform_device(dev); | ||
| 131 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
| 132 | |||
| 133 | if (ep93xx_pwm_is_enabled(pwm)) { | ||
| 134 | unsigned long rate = clk_get_rate(pwm->clk); | ||
| 135 | u16 term = ep93xx_pwm_read_tc(pwm); | ||
| 136 | |||
| 137 | return sprintf(buf, "%ld\n", rate / (term + 1)); | ||
| 138 | } else { | ||
| 139 | return sprintf(buf, "disabled\n"); | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | static ssize_t ep93xx_pwm_set_freq(struct device *dev, | ||
| 144 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 145 | { | ||
| 146 | struct platform_device *pdev = to_platform_device(dev); | ||
| 147 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
| 148 | long val; | ||
| 149 | int err; | ||
| 150 | |||
| 151 | err = strict_strtol(buf, 10, &val); | ||
| 152 | if (err) | ||
| 153 | return -EINVAL; | ||
| 154 | |||
| 155 | if (val == 0) { | ||
| 156 | ep93xx_pwm_disable(pwm); | ||
| 157 | } else if (val <= (clk_get_rate(pwm->clk) / 2)) { | ||
| 158 | u32 term, duty; | ||
| 159 | |||
| 160 | val = (clk_get_rate(pwm->clk) / val) - 1; | ||
| 161 | if (val > EP93XX_PWM_MAX_COUNT) | ||
| 162 | val = EP93XX_PWM_MAX_COUNT; | ||
| 163 | if (val < 1) | ||
| 164 | val = 1; | ||
| 165 | |||
| 166 | term = ep93xx_pwm_read_tc(pwm); | ||
| 167 | duty = ((val + 1) * pwm->duty_percent / 100) - 1; | ||
| 168 | |||
| 169 | /* If pwm is running, order is important */ | ||
| 170 | if (val > term) { | ||
| 171 | ep93xx_pwm_write_tc(pwm, val); | ||
| 172 | ep93xx_pwm_write_dc(pwm, duty); | ||
| 173 | } else { | ||
| 174 | ep93xx_pwm_write_dc(pwm, duty); | ||
| 175 | ep93xx_pwm_write_tc(pwm, val); | ||
| 176 | } | ||
| 177 | |||
| 178 | if (!ep93xx_pwm_is_enabled(pwm)) | ||
| 179 | ep93xx_pwm_enable(pwm); | ||
| 180 | } else { | ||
| 181 | return -EINVAL; | ||
| 182 | } | ||
| 183 | |||
| 184 | return count; | ||
| 185 | } | ||
| 186 | |||
| 187 | static ssize_t ep93xx_pwm_get_duty_percent(struct device *dev, | ||
| 188 | struct device_attribute *attr, char *buf) | ||
| 189 | { | ||
| 190 | struct platform_device *pdev = to_platform_device(dev); | ||
| 191 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
| 192 | |||
| 193 | return sprintf(buf, "%d\n", pwm->duty_percent); | ||
| 194 | } | ||
| 195 | |||
| 196 | static ssize_t ep93xx_pwm_set_duty_percent(struct device *dev, | ||
| 197 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 198 | { | ||
| 199 | struct platform_device *pdev = to_platform_device(dev); | ||
| 200 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
| 201 | long val; | ||
| 202 | int err; | ||
| 203 | |||
| 204 | err = strict_strtol(buf, 10, &val); | ||
| 205 | if (err) | ||
| 206 | return -EINVAL; | ||
| 207 | |||
| 208 | if (val > 0 && val < 100) { | ||
| 209 | u32 term = ep93xx_pwm_read_tc(pwm); | ||
| 210 | ep93xx_pwm_write_dc(pwm, ((term + 1) * val / 100) - 1); | ||
| 211 | pwm->duty_percent = val; | ||
| 212 | return count; | ||
| 213 | } | ||
| 214 | |||
| 215 | return -EINVAL; | ||
| 216 | } | ||
| 217 | |||
| 218 | static ssize_t ep93xx_pwm_get_invert(struct device *dev, | ||
| 219 | struct device_attribute *attr, char *buf) | ||
| 220 | { | ||
| 221 | struct platform_device *pdev = to_platform_device(dev); | ||
| 222 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
| 223 | |||
| 224 | return sprintf(buf, "%d\n", ep93xx_pwm_is_inverted(pwm)); | ||
| 225 | } | ||
| 226 | |||
| 227 | static ssize_t ep93xx_pwm_set_invert(struct device *dev, | ||
| 228 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 229 | { | ||
| 230 | struct platform_device *pdev = to_platform_device(dev); | ||
| 231 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
| 232 | long val; | ||
| 233 | int err; | ||
| 234 | |||
| 235 | err = strict_strtol(buf, 10, &val); | ||
| 236 | if (err) | ||
| 237 | return -EINVAL; | ||
| 238 | |||
| 239 | if (val == 0) | ||
| 240 | ep93xx_pwm_normal(pwm); | ||
| 241 | else if (val == 1) | ||
| 242 | ep93xx_pwm_invert(pwm); | ||
| 243 | else | ||
| 244 | return -EINVAL; | ||
| 245 | |||
| 246 | return count; | ||
| 247 | } | ||
| 248 | |||
| 249 | static DEVICE_ATTR(min_freq, S_IRUGO, ep93xx_pwm_get_min_freq, NULL); | ||
| 250 | static DEVICE_ATTR(max_freq, S_IRUGO, ep93xx_pwm_get_max_freq, NULL); | ||
| 251 | static DEVICE_ATTR(freq, S_IWUGO | S_IRUGO, | ||
| 252 | ep93xx_pwm_get_freq, ep93xx_pwm_set_freq); | ||
| 253 | static DEVICE_ATTR(duty_percent, S_IWUGO | S_IRUGO, | ||
| 254 | ep93xx_pwm_get_duty_percent, ep93xx_pwm_set_duty_percent); | ||
| 255 | static DEVICE_ATTR(invert, S_IWUGO | S_IRUGO, | ||
| 256 | ep93xx_pwm_get_invert, ep93xx_pwm_set_invert); | ||
| 257 | |||
| 258 | static struct attribute *ep93xx_pwm_attrs[] = { | ||
| 259 | &dev_attr_min_freq.attr, | ||
| 260 | &dev_attr_max_freq.attr, | ||
| 261 | &dev_attr_freq.attr, | ||
| 262 | &dev_attr_duty_percent.attr, | ||
| 263 | &dev_attr_invert.attr, | ||
| 264 | NULL | ||
| 265 | }; | ||
| 266 | |||
| 267 | static const struct attribute_group ep93xx_pwm_sysfs_files = { | ||
| 268 | .attrs = ep93xx_pwm_attrs, | ||
| 269 | }; | ||
| 270 | |||
| 271 | static int __init ep93xx_pwm_probe(struct platform_device *pdev) | ||
| 272 | { | ||
| 273 | struct ep93xx_pwm *pwm; | ||
| 274 | struct resource *res; | ||
| 275 | int err; | ||
| 276 | |||
| 277 | err = ep93xx_pwm_acquire_gpio(pdev); | ||
| 278 | if (err) | ||
| 279 | return err; | ||
| 280 | |||
| 281 | pwm = kzalloc(sizeof(struct ep93xx_pwm), GFP_KERNEL); | ||
| 282 | if (!pwm) { | ||
| 283 | err = -ENOMEM; | ||
| 284 | goto fail_no_mem; | ||
| 285 | } | ||
| 286 | |||
| 287 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 288 | if (res == NULL) { | ||
| 289 | err = -ENXIO; | ||
| 290 | goto fail_no_mem_resource; | ||
| 291 | } | ||
| 292 | |||
| 293 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
| 294 | if (res == NULL) { | ||
| 295 | err = -EBUSY; | ||
| 296 | goto fail_no_mem_resource; | ||
| 297 | } | ||
| 298 | |||
| 299 | pwm->mmio_base = ioremap(res->start, resource_size(res)); | ||
| 300 | if (pwm->mmio_base == NULL) { | ||
| 301 | err = -ENXIO; | ||
| 302 | goto fail_no_ioremap; | ||
| 303 | } | ||
| 304 | |||
| 305 | err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); | ||
| 306 | if (err) | ||
| 307 | goto fail_no_sysfs; | ||
| 308 | |||
| 309 | pwm->clk = clk_get(&pdev->dev, "pwm_clk"); | ||
| 310 | if (IS_ERR(pwm->clk)) { | ||
| 311 | err = PTR_ERR(pwm->clk); | ||
| 312 | goto fail_no_clk; | ||
| 313 | } | ||
| 314 | |||
| 315 | pwm->duty_percent = 50; | ||
| 316 | |||
| 317 | platform_set_drvdata(pdev, pwm); | ||
| 318 | |||
| 319 | /* disable pwm at startup. Avoids zero value. */ | ||
| 320 | ep93xx_pwm_disable(pwm); | ||
| 321 | ep93xx_pwm_write_tc(pwm, EP93XX_PWM_MAX_COUNT); | ||
| 322 | ep93xx_pwm_write_dc(pwm, EP93XX_PWM_MAX_COUNT / 2); | ||
| 323 | |||
| 324 | clk_enable(pwm->clk); | ||
| 325 | |||
| 326 | return 0; | ||
| 327 | |||
| 328 | fail_no_clk: | ||
| 329 | sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); | ||
| 330 | fail_no_sysfs: | ||
| 331 | iounmap(pwm->mmio_base); | ||
| 332 | fail_no_ioremap: | ||
| 333 | release_mem_region(res->start, resource_size(res)); | ||
| 334 | fail_no_mem_resource: | ||
| 335 | kfree(pwm); | ||
| 336 | fail_no_mem: | ||
| 337 | ep93xx_pwm_release_gpio(pdev); | ||
| 338 | return err; | ||
| 339 | } | ||
| 340 | |||
| 341 | static int __exit ep93xx_pwm_remove(struct platform_device *pdev) | ||
| 342 | { | ||
| 343 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
| 344 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 345 | |||
| 346 | ep93xx_pwm_disable(pwm); | ||
| 347 | clk_disable(pwm->clk); | ||
| 348 | clk_put(pwm->clk); | ||
| 349 | platform_set_drvdata(pdev, NULL); | ||
| 350 | sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); | ||
| 351 | iounmap(pwm->mmio_base); | ||
| 352 | release_mem_region(res->start, resource_size(res)); | ||
| 353 | kfree(pwm); | ||
| 354 | ep93xx_pwm_release_gpio(pdev); | ||
| 355 | |||
| 356 | return 0; | ||
| 357 | } | ||
| 358 | |||
| 359 | static struct platform_driver ep93xx_pwm_driver = { | ||
| 360 | .driver = { | ||
| 361 | .name = "ep93xx-pwm", | ||
| 362 | .owner = THIS_MODULE, | ||
| 363 | }, | ||
| 364 | .remove = __exit_p(ep93xx_pwm_remove), | ||
| 365 | }; | ||
| 366 | |||
| 367 | static int __init ep93xx_pwm_init(void) | ||
| 368 | { | ||
| 369 | return platform_driver_probe(&ep93xx_pwm_driver, ep93xx_pwm_probe); | ||
| 370 | } | ||
| 371 | |||
| 372 | static void __exit ep93xx_pwm_exit(void) | ||
| 373 | { | ||
| 374 | platform_driver_unregister(&ep93xx_pwm_driver); | ||
| 375 | } | ||
| 376 | |||
| 377 | module_init(ep93xx_pwm_init); | ||
| 378 | module_exit(ep93xx_pwm_exit); | ||
| 379 | |||
| 380 | MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>, " | ||
| 381 | "H Hartley Sweeten <hsweeten@visionengravers.com>"); | ||
| 382 | MODULE_DESCRIPTION("EP93xx PWM driver"); | ||
| 383 | MODULE_LICENSE("GPL"); | ||
| 384 | MODULE_ALIAS("platform:ep93xx-pwm"); | ||
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index 880ccf39e23b..a92a3a742b43 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c | |||
| @@ -13,14 +13,18 @@ | |||
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
| 15 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
| 16 | #include <linux/interrupt.h> | ||
| 16 | #include <linux/ioport.h> | 17 | #include <linux/ioport.h> |
| 17 | #include <linux/device.h> | 18 | #include <linux/device.h> |
| 18 | #include <linux/file.h> | 19 | #include <linux/file.h> |
| 19 | #include <linux/cdev.h> | 20 | #include <linux/cdev.h> |
| 21 | #include <linux/sched.h> | ||
| 20 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
| 21 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
| 22 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
| 23 | #include <linux/io.h> | 25 | #include <linux/io.h> |
| 26 | #include <linux/wait.h> | ||
| 27 | #include <linux/poll.h> | ||
| 24 | #include "hpilo.h" | 28 | #include "hpilo.h" |
| 25 | 29 | ||
| 26 | static struct class *ilo_class; | 30 | static struct class *ilo_class; |
| @@ -61,9 +65,10 @@ static inline int desc_mem_sz(int nr_entry) | |||
| 61 | static int fifo_enqueue(struct ilo_hwinfo *hw, char *fifobar, int entry) | 65 | static int fifo_enqueue(struct ilo_hwinfo *hw, char *fifobar, int entry) |
| 62 | { | 66 | { |
| 63 | struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar); | 67 | struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar); |
| 68 | unsigned long flags; | ||
| 64 | int ret = 0; | 69 | int ret = 0; |
| 65 | 70 | ||
| 66 | spin_lock(&hw->fifo_lock); | 71 | spin_lock_irqsave(&hw->fifo_lock, flags); |
| 67 | if (!(fifo_q->fifobar[(fifo_q->tail + 1) & fifo_q->imask] | 72 | if (!(fifo_q->fifobar[(fifo_q->tail + 1) & fifo_q->imask] |
| 68 | & ENTRY_MASK_O)) { | 73 | & ENTRY_MASK_O)) { |
| 69 | fifo_q->fifobar[fifo_q->tail & fifo_q->imask] |= | 74 | fifo_q->fifobar[fifo_q->tail & fifo_q->imask] |= |
| @@ -71,7 +76,7 @@ static int fifo_enqueue(struct ilo_hwinfo *hw, char *fifobar, int entry) | |||
| 71 | fifo_q->tail += 1; | 76 | fifo_q->tail += 1; |
| 72 | ret = 1; | 77 | ret = 1; |
| 73 | } | 78 | } |
| 74 | spin_unlock(&hw->fifo_lock); | 79 | spin_unlock_irqrestore(&hw->fifo_lock, flags); |
| 75 | 80 | ||
| 76 | return ret; | 81 | return ret; |
| 77 | } | 82 | } |
| @@ -79,10 +84,11 @@ static int fifo_enqueue(struct ilo_hwinfo *hw, char *fifobar, int entry) | |||
| 79 | static int fifo_dequeue(struct ilo_hwinfo *hw, char *fifobar, int *entry) | 84 | static int fifo_dequeue(struct ilo_hwinfo *hw, char *fifobar, int *entry) |
| 80 | { | 85 | { |
| 81 | struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar); | 86 | struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar); |
| 87 | unsigned long flags; | ||
| 82 | int ret = 0; | 88 | int ret = 0; |
| 83 | u64 c; | 89 | u64 c; |
| 84 | 90 | ||
| 85 | spin_lock(&hw->fifo_lock); | 91 | spin_lock_irqsave(&hw->fifo_lock, flags); |
| 86 | c = fifo_q->fifobar[fifo_q->head & fifo_q->imask]; | 92 | c = fifo_q->fifobar[fifo_q->head & fifo_q->imask]; |
| 87 | if (c & ENTRY_MASK_C) { | 93 | if (c & ENTRY_MASK_C) { |
| 88 | if (entry) | 94 | if (entry) |
| @@ -93,7 +99,23 @@ static int fifo_dequeue(struct ilo_hwinfo *hw, char *fifobar, int *entry) | |||
| 93 | fifo_q->head += 1; | 99 | fifo_q->head += 1; |
| 94 | ret = 1; | 100 | ret = 1; |
| 95 | } | 101 | } |
| 96 | spin_unlock(&hw->fifo_lock); | 102 | spin_unlock_irqrestore(&hw->fifo_lock, flags); |
| 103 | |||
| 104 | return ret; | ||
| 105 | } | ||
| 106 | |||
| 107 | static int fifo_check_recv(struct ilo_hwinfo *hw, char *fifobar) | ||
| 108 | { | ||
| 109 | struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar); | ||
| 110 | unsigned long flags; | ||
| 111 | int ret = 0; | ||
| 112 | u64 c; | ||
| 113 | |||
| 114 | spin_lock_irqsave(&hw->fifo_lock, flags); | ||
| 115 | c = fifo_q->fifobar[fifo_q->head & fifo_q->imask]; | ||
| 116 | if (c & ENTRY_MASK_C) | ||
| 117 | ret = 1; | ||
| 118 | spin_unlock_irqrestore(&hw->fifo_lock, flags); | ||
| 97 | 119 | ||
| 98 | return ret; | 120 | return ret; |
| 99 | } | 121 | } |
| @@ -142,6 +164,13 @@ static int ilo_pkt_dequeue(struct ilo_hwinfo *hw, struct ccb *ccb, | |||
| 142 | return ret; | 164 | return ret; |
| 143 | } | 165 | } |
| 144 | 166 | ||
| 167 | static int ilo_pkt_recv(struct ilo_hwinfo *hw, struct ccb *ccb) | ||
| 168 | { | ||
| 169 | char *fifobar = ccb->ccb_u3.recv_fifobar; | ||
| 170 | |||
| 171 | return fifo_check_recv(hw, fifobar); | ||
| 172 | } | ||
| 173 | |||
| 145 | static inline void doorbell_set(struct ccb *ccb) | 174 | static inline void doorbell_set(struct ccb *ccb) |
| 146 | { | 175 | { |
| 147 | iowrite8(1, ccb->ccb_u5.db_base); | 176 | iowrite8(1, ccb->ccb_u5.db_base); |
| @@ -151,6 +180,7 @@ static inline void doorbell_clr(struct ccb *ccb) | |||
| 151 | { | 180 | { |
| 152 | iowrite8(2, ccb->ccb_u5.db_base); | 181 | iowrite8(2, ccb->ccb_u5.db_base); |
| 153 | } | 182 | } |
| 183 | |||
| 154 | static inline int ctrl_set(int l2sz, int idxmask, int desclim) | 184 | static inline int ctrl_set(int l2sz, int idxmask, int desclim) |
| 155 | { | 185 | { |
| 156 | int active = 0, go = 1; | 186 | int active = 0, go = 1; |
| @@ -160,6 +190,7 @@ static inline int ctrl_set(int l2sz, int idxmask, int desclim) | |||
| 160 | active << CTRL_BITPOS_A | | 190 | active << CTRL_BITPOS_A | |
| 161 | go << CTRL_BITPOS_G; | 191 | go << CTRL_BITPOS_G; |
| 162 | } | 192 | } |
| 193 | |||
| 163 | static void ctrl_setup(struct ccb *ccb, int nr_desc, int l2desc_sz) | 194 | static void ctrl_setup(struct ccb *ccb, int nr_desc, int l2desc_sz) |
| 164 | { | 195 | { |
| 165 | /* for simplicity, use the same parameters for send and recv ctrls */ | 196 | /* for simplicity, use the same parameters for send and recv ctrls */ |
| @@ -192,13 +223,10 @@ static void fifo_setup(void *base_addr, int nr_entry) | |||
| 192 | 223 | ||
| 193 | static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data) | 224 | static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data) |
| 194 | { | 225 | { |
| 195 | struct ccb *driver_ccb; | 226 | struct ccb *driver_ccb = &data->driver_ccb; |
| 196 | struct ccb __iomem *device_ccb; | 227 | struct ccb __iomem *device_ccb = data->mapped_ccb; |
| 197 | int retries; | 228 | int retries; |
| 198 | 229 | ||
| 199 | driver_ccb = &data->driver_ccb; | ||
| 200 | device_ccb = data->mapped_ccb; | ||
| 201 | |||
| 202 | /* complicated dance to tell the hw we are stopping */ | 230 | /* complicated dance to tell the hw we are stopping */ |
| 203 | doorbell_clr(driver_ccb); | 231 | doorbell_clr(driver_ccb); |
| 204 | iowrite32(ioread32(&device_ccb->send_ctrl) & ~(1 << CTRL_BITPOS_G), | 232 | iowrite32(ioread32(&device_ccb->send_ctrl) & ~(1 << CTRL_BITPOS_G), |
| @@ -225,26 +253,22 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data) | |||
| 225 | pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa); | 253 | pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa); |
| 226 | } | 254 | } |
| 227 | 255 | ||
| 228 | static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) | 256 | static int ilo_ccb_setup(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) |
| 229 | { | 257 | { |
| 230 | char *dma_va, *dma_pa; | 258 | char *dma_va, *dma_pa; |
| 231 | int pkt_id, pkt_sz, i, error; | ||
| 232 | struct ccb *driver_ccb, *ilo_ccb; | 259 | struct ccb *driver_ccb, *ilo_ccb; |
| 233 | struct pci_dev *pdev; | ||
| 234 | 260 | ||
| 235 | driver_ccb = &data->driver_ccb; | 261 | driver_ccb = &data->driver_ccb; |
| 236 | ilo_ccb = &data->ilo_ccb; | 262 | ilo_ccb = &data->ilo_ccb; |
| 237 | pdev = hw->ilo_dev; | ||
| 238 | 263 | ||
| 239 | data->dma_size = 2 * fifo_sz(NR_QENTRY) + | 264 | data->dma_size = 2 * fifo_sz(NR_QENTRY) + |
| 240 | 2 * desc_mem_sz(NR_QENTRY) + | 265 | 2 * desc_mem_sz(NR_QENTRY) + |
| 241 | ILO_START_ALIGN + ILO_CACHE_SZ; | 266 | ILO_START_ALIGN + ILO_CACHE_SZ; |
| 242 | 267 | ||
| 243 | error = -ENOMEM; | 268 | data->dma_va = pci_alloc_consistent(hw->ilo_dev, data->dma_size, |
| 244 | data->dma_va = pci_alloc_consistent(pdev, data->dma_size, | ||
| 245 | &data->dma_pa); | 269 | &data->dma_pa); |
| 246 | if (!data->dma_va) | 270 | if (!data->dma_va) |
| 247 | goto out; | 271 | return -ENOMEM; |
| 248 | 272 | ||
| 249 | dma_va = (char *)data->dma_va; | 273 | dma_va = (char *)data->dma_va; |
| 250 | dma_pa = (char *)data->dma_pa; | 274 | dma_pa = (char *)data->dma_pa; |
| @@ -290,10 +314,18 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) | |||
| 290 | driver_ccb->ccb_u5.db_base = hw->db_vaddr + (slot << L2_DB_SIZE); | 314 | driver_ccb->ccb_u5.db_base = hw->db_vaddr + (slot << L2_DB_SIZE); |
| 291 | ilo_ccb->ccb_u5.db_base = NULL; /* hw ccb's doorbell is not used */ | 315 | ilo_ccb->ccb_u5.db_base = NULL; /* hw ccb's doorbell is not used */ |
| 292 | 316 | ||
| 317 | return 0; | ||
| 318 | } | ||
| 319 | |||
| 320 | static void ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) | ||
| 321 | { | ||
| 322 | int pkt_id, pkt_sz; | ||
| 323 | struct ccb *driver_ccb = &data->driver_ccb; | ||
| 324 | |||
| 293 | /* copy the ccb with physical addrs to device memory */ | 325 | /* copy the ccb with physical addrs to device memory */ |
| 294 | data->mapped_ccb = (struct ccb __iomem *) | 326 | data->mapped_ccb = (struct ccb __iomem *) |
| 295 | (hw->ram_vaddr + (slot * ILOHW_CCB_SZ)); | 327 | (hw->ram_vaddr + (slot * ILOHW_CCB_SZ)); |
| 296 | memcpy_toio(data->mapped_ccb, ilo_ccb, sizeof(struct ccb)); | 328 | memcpy_toio(data->mapped_ccb, &data->ilo_ccb, sizeof(struct ccb)); |
| 297 | 329 | ||
| 298 | /* put packets on the send and receive queues */ | 330 | /* put packets on the send and receive queues */ |
| 299 | pkt_sz = 0; | 331 | pkt_sz = 0; |
| @@ -306,7 +338,14 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) | |||
| 306 | for (pkt_id = 0; pkt_id < NR_QENTRY; pkt_id++) | 338 | for (pkt_id = 0; pkt_id < NR_QENTRY; pkt_id++) |
| 307 | ilo_pkt_enqueue(hw, driver_ccb, RECVQ, pkt_id, pkt_sz); | 339 | ilo_pkt_enqueue(hw, driver_ccb, RECVQ, pkt_id, pkt_sz); |
| 308 | 340 | ||
| 341 | /* the ccb is ready to use */ | ||
| 309 | doorbell_clr(driver_ccb); | 342 | doorbell_clr(driver_ccb); |
| 343 | } | ||
| 344 | |||
| 345 | static int ilo_ccb_verify(struct ilo_hwinfo *hw, struct ccb_data *data) | ||
| 346 | { | ||
| 347 | int pkt_id, i; | ||
| 348 | struct ccb *driver_ccb = &data->driver_ccb; | ||
| 310 | 349 | ||
| 311 | /* make sure iLO is really handling requests */ | 350 | /* make sure iLO is really handling requests */ |
| 312 | for (i = MAX_WAIT; i > 0; i--) { | 351 | for (i = MAX_WAIT; i > 0; i--) { |
| @@ -315,20 +354,14 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot) | |||
| 315 | udelay(WAIT_TIME); | 354 | udelay(WAIT_TIME); |
| 316 | } | 355 | } |
| 317 | 356 | ||
| 318 | if (i) { | 357 | if (i == 0) { |
| 319 | ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, 0); | 358 | dev_err(&hw->ilo_dev->dev, "Open could not dequeue a packet\n"); |
| 320 | doorbell_set(driver_ccb); | 359 | return -EBUSY; |
| 321 | } else { | ||
| 322 | dev_err(&pdev->dev, "Open could not dequeue a packet\n"); | ||
| 323 | error = -EBUSY; | ||
| 324 | goto free; | ||
| 325 | } | 360 | } |
| 326 | 361 | ||
| 362 | ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, 0); | ||
| 363 | doorbell_set(driver_ccb); | ||
| 327 | return 0; | 364 | return 0; |
| 328 | free: | ||
| 329 | ilo_ccb_close(pdev, data); | ||
| 330 | out: | ||
| 331 | return error; | ||
| 332 | } | 365 | } |
| 333 | 366 | ||
| 334 | static inline int is_channel_reset(struct ccb *ccb) | 367 | static inline int is_channel_reset(struct ccb *ccb) |
| @@ -343,19 +376,45 @@ static inline void set_channel_reset(struct ccb *ccb) | |||
| 343 | FIFOBARTOHANDLE(ccb->ccb_u1.send_fifobar)->reset = 1; | 376 | FIFOBARTOHANDLE(ccb->ccb_u1.send_fifobar)->reset = 1; |
| 344 | } | 377 | } |
| 345 | 378 | ||
| 379 | static inline int get_device_outbound(struct ilo_hwinfo *hw) | ||
| 380 | { | ||
| 381 | return ioread32(&hw->mmio_vaddr[DB_OUT]); | ||
| 382 | } | ||
| 383 | |||
| 384 | static inline int is_db_reset(int db_out) | ||
| 385 | { | ||
| 386 | return db_out & (1 << DB_RESET); | ||
| 387 | } | ||
| 388 | |||
| 346 | static inline int is_device_reset(struct ilo_hwinfo *hw) | 389 | static inline int is_device_reset(struct ilo_hwinfo *hw) |
| 347 | { | 390 | { |
| 348 | /* check for global reset condition */ | 391 | /* check for global reset condition */ |
| 349 | return ioread32(&hw->mmio_vaddr[DB_OUT]) & (1 << DB_RESET); | 392 | return is_db_reset(get_device_outbound(hw)); |
| 393 | } | ||
| 394 | |||
| 395 | static inline void clear_pending_db(struct ilo_hwinfo *hw, int clr) | ||
| 396 | { | ||
| 397 | iowrite32(clr, &hw->mmio_vaddr[DB_OUT]); | ||
| 350 | } | 398 | } |
| 351 | 399 | ||
| 352 | static inline void clear_device(struct ilo_hwinfo *hw) | 400 | static inline void clear_device(struct ilo_hwinfo *hw) |
| 353 | { | 401 | { |
| 354 | /* clear the device (reset bits, pending channel entries) */ | 402 | /* clear the device (reset bits, pending channel entries) */ |
| 355 | iowrite32(-1, &hw->mmio_vaddr[DB_OUT]); | 403 | clear_pending_db(hw, -1); |
| 404 | } | ||
| 405 | |||
| 406 | static inline void ilo_enable_interrupts(struct ilo_hwinfo *hw) | ||
| 407 | { | ||
| 408 | iowrite8(ioread8(&hw->mmio_vaddr[DB_IRQ]) | 1, &hw->mmio_vaddr[DB_IRQ]); | ||
| 356 | } | 409 | } |
| 357 | 410 | ||
| 358 | static void ilo_locked_reset(struct ilo_hwinfo *hw) | 411 | static inline void ilo_disable_interrupts(struct ilo_hwinfo *hw) |
| 412 | { | ||
| 413 | iowrite8(ioread8(&hw->mmio_vaddr[DB_IRQ]) & ~1, | ||
| 414 | &hw->mmio_vaddr[DB_IRQ]); | ||
| 415 | } | ||
| 416 | |||
| 417 | static void ilo_set_reset(struct ilo_hwinfo *hw) | ||
| 359 | { | 418 | { |
| 360 | int slot; | 419 | int slot; |
| 361 | 420 | ||
| @@ -368,40 +427,22 @@ static void ilo_locked_reset(struct ilo_hwinfo *hw) | |||
| 368 | continue; | 427 | continue; |
| 369 | set_channel_reset(&hw->ccb_alloc[slot]->driver_ccb); | 428 | set_channel_reset(&hw->ccb_alloc[slot]->driver_ccb); |
| 370 | } | 429 | } |
| 371 | |||
| 372 | clear_device(hw); | ||
| 373 | } | ||
| 374 | |||
| 375 | static void ilo_reset(struct ilo_hwinfo *hw) | ||
| 376 | { | ||
| 377 | spin_lock(&hw->alloc_lock); | ||
| 378 | |||
| 379 | /* reset might have been handled after lock was taken */ | ||
| 380 | if (is_device_reset(hw)) | ||
| 381 | ilo_locked_reset(hw); | ||
| 382 | |||
| 383 | spin_unlock(&hw->alloc_lock); | ||
| 384 | } | 430 | } |
| 385 | 431 | ||
| 386 | static ssize_t ilo_read(struct file *fp, char __user *buf, | 432 | static ssize_t ilo_read(struct file *fp, char __user *buf, |
| 387 | size_t len, loff_t *off) | 433 | size_t len, loff_t *off) |
| 388 | { | 434 | { |
| 389 | int err, found, cnt, pkt_id, pkt_len; | 435 | int err, found, cnt, pkt_id, pkt_len; |
| 390 | struct ccb_data *data; | 436 | struct ccb_data *data = fp->private_data; |
| 391 | struct ccb *driver_ccb; | 437 | struct ccb *driver_ccb = &data->driver_ccb; |
| 392 | struct ilo_hwinfo *hw; | 438 | struct ilo_hwinfo *hw = data->ilo_hw; |
| 393 | void *pkt; | 439 | void *pkt; |
| 394 | 440 | ||
| 395 | data = fp->private_data; | 441 | if (is_channel_reset(driver_ccb)) { |
| 396 | driver_ccb = &data->driver_ccb; | ||
| 397 | hw = data->ilo_hw; | ||
| 398 | |||
| 399 | if (is_device_reset(hw) || is_channel_reset(driver_ccb)) { | ||
| 400 | /* | 442 | /* |
| 401 | * If the device has been reset, applications | 443 | * If the device has been reset, applications |
| 402 | * need to close and reopen all ccbs. | 444 | * need to close and reopen all ccbs. |
| 403 | */ | 445 | */ |
| 404 | ilo_reset(hw); | ||
| 405 | return -ENODEV; | 446 | return -ENODEV; |
| 406 | } | 447 | } |
| 407 | 448 | ||
| @@ -442,23 +483,13 @@ static ssize_t ilo_write(struct file *fp, const char __user *buf, | |||
| 442 | size_t len, loff_t *off) | 483 | size_t len, loff_t *off) |
| 443 | { | 484 | { |
| 444 | int err, pkt_id, pkt_len; | 485 | int err, pkt_id, pkt_len; |
| 445 | struct ccb_data *data; | 486 | struct ccb_data *data = fp->private_data; |
| 446 | struct ccb *driver_ccb; | 487 | struct ccb *driver_ccb = &data->driver_ccb; |
| 447 | struct ilo_hwinfo *hw; | 488 | struct ilo_hwinfo *hw = data->ilo_hw; |
| 448 | void *pkt; | 489 | void *pkt; |
| 449 | 490 | ||
| 450 | data = fp->private_data; | 491 | if (is_channel_reset(driver_ccb)) |
| 451 | driver_ccb = &data->driver_ccb; | ||
| 452 | hw = data->ilo_hw; | ||
| 453 | |||
| 454 | if (is_device_reset(hw) || is_channel_reset(driver_ccb)) { | ||
| 455 | /* | ||
| 456 | * If the device has been reset, applications | ||
| 457 | * need to close and reopen all ccbs. | ||
| 458 | */ | ||
| 459 | ilo_reset(hw); | ||
| 460 | return -ENODEV; | 492 | return -ENODEV; |
| 461 | } | ||
| 462 | 493 | ||
| 463 | /* get a packet to send the user command */ | 494 | /* get a packet to send the user command */ |
| 464 | if (!ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, &pkt_len, &pkt)) | 495 | if (!ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, &pkt_len, &pkt)) |
| @@ -480,32 +511,48 @@ static ssize_t ilo_write(struct file *fp, const char __user *buf, | |||
| 480 | return err ? -EFAULT : len; | 511 | return err ? -EFAULT : len; |
| 481 | } | 512 | } |
| 482 | 513 | ||
| 514 | static unsigned int ilo_poll(struct file *fp, poll_table *wait) | ||
| 515 | { | ||
| 516 | struct ccb_data *data = fp->private_data; | ||
| 517 | struct ccb *driver_ccb = &data->driver_ccb; | ||
| 518 | |||
| 519 | poll_wait(fp, &data->ccb_waitq, wait); | ||
| 520 | |||
| 521 | if (is_channel_reset(driver_ccb)) | ||
| 522 | return POLLERR; | ||
| 523 | else if (ilo_pkt_recv(data->ilo_hw, driver_ccb)) | ||
| 524 | return POLLIN | POLLRDNORM; | ||
| 525 | |||
| 526 | return 0; | ||
| 527 | } | ||
| 528 | |||
| 483 | static int ilo_close(struct inode *ip, struct file *fp) | 529 | static int ilo_close(struct inode *ip, struct file *fp) |
| 484 | { | 530 | { |
| 485 | int slot; | 531 | int slot; |
| 486 | struct ccb_data *data; | 532 | struct ccb_data *data; |
| 487 | struct ilo_hwinfo *hw; | 533 | struct ilo_hwinfo *hw; |
| 534 | unsigned long flags; | ||
| 488 | 535 | ||
| 489 | slot = iminor(ip) % MAX_CCB; | 536 | slot = iminor(ip) % MAX_CCB; |
| 490 | hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev); | 537 | hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev); |
| 491 | 538 | ||
| 492 | spin_lock(&hw->alloc_lock); | 539 | spin_lock(&hw->open_lock); |
| 493 | |||
| 494 | if (is_device_reset(hw)) | ||
| 495 | ilo_locked_reset(hw); | ||
| 496 | 540 | ||
| 497 | if (hw->ccb_alloc[slot]->ccb_cnt == 1) { | 541 | if (hw->ccb_alloc[slot]->ccb_cnt == 1) { |
| 498 | 542 | ||
| 499 | data = fp->private_data; | 543 | data = fp->private_data; |
| 500 | 544 | ||
| 545 | spin_lock_irqsave(&hw->alloc_lock, flags); | ||
| 546 | hw->ccb_alloc[slot] = NULL; | ||
| 547 | spin_unlock_irqrestore(&hw->alloc_lock, flags); | ||
| 548 | |||
| 501 | ilo_ccb_close(hw->ilo_dev, data); | 549 | ilo_ccb_close(hw->ilo_dev, data); |
| 502 | 550 | ||
| 503 | kfree(data); | 551 | kfree(data); |
| 504 | hw->ccb_alloc[slot] = NULL; | ||
| 505 | } else | 552 | } else |
| 506 | hw->ccb_alloc[slot]->ccb_cnt--; | 553 | hw->ccb_alloc[slot]->ccb_cnt--; |
| 507 | 554 | ||
| 508 | spin_unlock(&hw->alloc_lock); | 555 | spin_unlock(&hw->open_lock); |
| 509 | 556 | ||
| 510 | return 0; | 557 | return 0; |
| 511 | } | 558 | } |
| @@ -515,6 +562,7 @@ static int ilo_open(struct inode *ip, struct file *fp) | |||
| 515 | int slot, error; | 562 | int slot, error; |
| 516 | struct ccb_data *data; | 563 | struct ccb_data *data; |
| 517 | struct ilo_hwinfo *hw; | 564 | struct ilo_hwinfo *hw; |
| 565 | unsigned long flags; | ||
| 518 | 566 | ||
| 519 | slot = iminor(ip) % MAX_CCB; | 567 | slot = iminor(ip) % MAX_CCB; |
| 520 | hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev); | 568 | hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev); |
| @@ -524,22 +572,42 @@ static int ilo_open(struct inode *ip, struct file *fp) | |||
| 524 | if (!data) | 572 | if (!data) |
| 525 | return -ENOMEM; | 573 | return -ENOMEM; |
| 526 | 574 | ||
| 527 | spin_lock(&hw->alloc_lock); | 575 | spin_lock(&hw->open_lock); |
| 528 | |||
| 529 | if (is_device_reset(hw)) | ||
| 530 | ilo_locked_reset(hw); | ||
| 531 | 576 | ||
| 532 | /* each fd private_data holds sw/hw view of ccb */ | 577 | /* each fd private_data holds sw/hw view of ccb */ |
| 533 | if (hw->ccb_alloc[slot] == NULL) { | 578 | if (hw->ccb_alloc[slot] == NULL) { |
| 534 | /* create a channel control block for this minor */ | 579 | /* create a channel control block for this minor */ |
| 535 | error = ilo_ccb_open(hw, data, slot); | 580 | error = ilo_ccb_setup(hw, data, slot); |
| 536 | if (!error) { | 581 | if (error) { |
| 537 | hw->ccb_alloc[slot] = data; | ||
| 538 | hw->ccb_alloc[slot]->ccb_cnt = 1; | ||
| 539 | hw->ccb_alloc[slot]->ccb_excl = fp->f_flags & O_EXCL; | ||
| 540 | hw->ccb_alloc[slot]->ilo_hw = hw; | ||
| 541 | } else | ||
| 542 | kfree(data); | 582 | kfree(data); |
| 583 | goto out; | ||
| 584 | } | ||
| 585 | |||
| 586 | data->ccb_cnt = 1; | ||
| 587 | data->ccb_excl = fp->f_flags & O_EXCL; | ||
| 588 | data->ilo_hw = hw; | ||
| 589 | init_waitqueue_head(&data->ccb_waitq); | ||
| 590 | |||
| 591 | /* write the ccb to hw */ | ||
| 592 | spin_lock_irqsave(&hw->alloc_lock, flags); | ||
| 593 | ilo_ccb_open(hw, data, slot); | ||
| 594 | hw->ccb_alloc[slot] = data; | ||
| 595 | spin_unlock_irqrestore(&hw->alloc_lock, flags); | ||
| 596 | |||
| 597 | /* make sure the channel is functional */ | ||
| 598 | error = ilo_ccb_verify(hw, data); | ||
| 599 | if (error) { | ||
| 600 | |||
| 601 | spin_lock_irqsave(&hw->alloc_lock, flags); | ||
| 602 | hw->ccb_alloc[slot] = NULL; | ||
| 603 | spin_unlock_irqrestore(&hw->alloc_lock, flags); | ||
| 604 | |||
| 605 | ilo_ccb_close(hw->ilo_dev, data); | ||
| 606 | |||
| 607 | kfree(data); | ||
| 608 | goto out; | ||
| 609 | } | ||
| 610 | |||
| 543 | } else { | 611 | } else { |
| 544 | kfree(data); | 612 | kfree(data); |
| 545 | if (fp->f_flags & O_EXCL || hw->ccb_alloc[slot]->ccb_excl) { | 613 | if (fp->f_flags & O_EXCL || hw->ccb_alloc[slot]->ccb_excl) { |
| @@ -554,7 +622,8 @@ static int ilo_open(struct inode *ip, struct file *fp) | |||
| 554 | error = 0; | 622 | error = 0; |
| 555 | } | 623 | } |
| 556 | } | 624 | } |
| 557 | spin_unlock(&hw->alloc_lock); | 625 | out: |
| 626 | spin_unlock(&hw->open_lock); | ||
| 558 | 627 | ||
| 559 | if (!error) | 628 | if (!error) |
| 560 | fp->private_data = hw->ccb_alloc[slot]; | 629 | fp->private_data = hw->ccb_alloc[slot]; |
| @@ -566,10 +635,46 @@ static const struct file_operations ilo_fops = { | |||
| 566 | .owner = THIS_MODULE, | 635 | .owner = THIS_MODULE, |
| 567 | .read = ilo_read, | 636 | .read = ilo_read, |
| 568 | .write = ilo_write, | 637 | .write = ilo_write, |
| 638 | .poll = ilo_poll, | ||
| 569 | .open = ilo_open, | 639 | .open = ilo_open, |
| 570 | .release = ilo_close, | 640 | .release = ilo_close, |
| 571 | }; | 641 | }; |
| 572 | 642 | ||
| 643 | static irqreturn_t ilo_isr(int irq, void *data) | ||
| 644 | { | ||
| 645 | struct ilo_hwinfo *hw = data; | ||
| 646 | int pending, i; | ||
| 647 | |||
| 648 | spin_lock(&hw->alloc_lock); | ||
| 649 | |||
| 650 | /* check for ccbs which have data */ | ||
| 651 | pending = get_device_outbound(hw); | ||
| 652 | if (!pending) { | ||
| 653 | spin_unlock(&hw->alloc_lock); | ||
| 654 | return IRQ_NONE; | ||
| 655 | } | ||
| 656 | |||
| 657 | if (is_db_reset(pending)) { | ||
| 658 | /* wake up all ccbs if the device was reset */ | ||
| 659 | pending = -1; | ||
| 660 | ilo_set_reset(hw); | ||
| 661 | } | ||
| 662 | |||
| 663 | for (i = 0; i < MAX_CCB; i++) { | ||
| 664 | if (!hw->ccb_alloc[i]) | ||
| 665 | continue; | ||
| 666 | if (pending & (1 << i)) | ||
| 667 | wake_up_interruptible(&hw->ccb_alloc[i]->ccb_waitq); | ||
| 668 | } | ||
| 669 | |||
| 670 | /* clear the device of the channels that have been handled */ | ||
| 671 | clear_pending_db(hw, pending); | ||
| 672 | |||
| 673 | spin_unlock(&hw->alloc_lock); | ||
| 674 | |||
| 675 | return IRQ_HANDLED; | ||
| 676 | } | ||
| 677 | |||
| 573 | static void ilo_unmap_device(struct pci_dev *pdev, struct ilo_hwinfo *hw) | 678 | static void ilo_unmap_device(struct pci_dev *pdev, struct ilo_hwinfo *hw) |
| 574 | { | 679 | { |
| 575 | pci_iounmap(pdev, hw->db_vaddr); | 680 | pci_iounmap(pdev, hw->db_vaddr); |
| @@ -623,6 +728,8 @@ static void ilo_remove(struct pci_dev *pdev) | |||
| 623 | device_destroy(ilo_class, MKDEV(ilo_major, i)); | 728 | device_destroy(ilo_class, MKDEV(ilo_major, i)); |
| 624 | 729 | ||
| 625 | cdev_del(&ilo_hw->cdev); | 730 | cdev_del(&ilo_hw->cdev); |
| 731 | ilo_disable_interrupts(ilo_hw); | ||
| 732 | free_irq(pdev->irq, ilo_hw); | ||
| 626 | ilo_unmap_device(pdev, ilo_hw); | 733 | ilo_unmap_device(pdev, ilo_hw); |
| 627 | pci_release_regions(pdev); | 734 | pci_release_regions(pdev); |
| 628 | pci_disable_device(pdev); | 735 | pci_disable_device(pdev); |
| @@ -658,6 +765,7 @@ static int __devinit ilo_probe(struct pci_dev *pdev, | |||
| 658 | ilo_hw->ilo_dev = pdev; | 765 | ilo_hw->ilo_dev = pdev; |
| 659 | spin_lock_init(&ilo_hw->alloc_lock); | 766 | spin_lock_init(&ilo_hw->alloc_lock); |
| 660 | spin_lock_init(&ilo_hw->fifo_lock); | 767 | spin_lock_init(&ilo_hw->fifo_lock); |
| 768 | spin_lock_init(&ilo_hw->open_lock); | ||
| 661 | 769 | ||
| 662 | error = pci_enable_device(pdev); | 770 | error = pci_enable_device(pdev); |
| 663 | if (error) | 771 | if (error) |
| @@ -676,13 +784,19 @@ static int __devinit ilo_probe(struct pci_dev *pdev, | |||
| 676 | pci_set_drvdata(pdev, ilo_hw); | 784 | pci_set_drvdata(pdev, ilo_hw); |
| 677 | clear_device(ilo_hw); | 785 | clear_device(ilo_hw); |
| 678 | 786 | ||
| 787 | error = request_irq(pdev->irq, ilo_isr, IRQF_SHARED, "hpilo", ilo_hw); | ||
| 788 | if (error) | ||
| 789 | goto unmap; | ||
| 790 | |||
| 791 | ilo_enable_interrupts(ilo_hw); | ||
| 792 | |||
| 679 | cdev_init(&ilo_hw->cdev, &ilo_fops); | 793 | cdev_init(&ilo_hw->cdev, &ilo_fops); |
| 680 | ilo_hw->cdev.owner = THIS_MODULE; | 794 | ilo_hw->cdev.owner = THIS_MODULE; |
| 681 | start = devnum * MAX_CCB; | 795 | start = devnum * MAX_CCB; |
| 682 | error = cdev_add(&ilo_hw->cdev, MKDEV(ilo_major, start), MAX_CCB); | 796 | error = cdev_add(&ilo_hw->cdev, MKDEV(ilo_major, start), MAX_CCB); |
| 683 | if (error) { | 797 | if (error) { |
| 684 | dev_err(&pdev->dev, "Could not add cdev\n"); | 798 | dev_err(&pdev->dev, "Could not add cdev\n"); |
| 685 | goto unmap; | 799 | goto remove_isr; |
| 686 | } | 800 | } |
| 687 | 801 | ||
| 688 | for (minor = 0 ; minor < MAX_CCB; minor++) { | 802 | for (minor = 0 ; minor < MAX_CCB; minor++) { |
| @@ -695,6 +809,9 @@ static int __devinit ilo_probe(struct pci_dev *pdev, | |||
| 695 | } | 809 | } |
| 696 | 810 | ||
| 697 | return 0; | 811 | return 0; |
| 812 | remove_isr: | ||
| 813 | ilo_disable_interrupts(ilo_hw); | ||
| 814 | free_irq(pdev->irq, ilo_hw); | ||
| 698 | unmap: | 815 | unmap: |
| 699 | ilo_unmap_device(pdev, ilo_hw); | 816 | ilo_unmap_device(pdev, ilo_hw); |
| 700 | free_regions: | 817 | free_regions: |
| @@ -759,7 +876,7 @@ static void __exit ilo_exit(void) | |||
| 759 | class_destroy(ilo_class); | 876 | class_destroy(ilo_class); |
| 760 | } | 877 | } |
| 761 | 878 | ||
| 762 | MODULE_VERSION("1.1"); | 879 | MODULE_VERSION("1.2"); |
| 763 | MODULE_ALIAS(ILO_NAME); | 880 | MODULE_ALIAS(ILO_NAME); |
| 764 | MODULE_DESCRIPTION(ILO_NAME); | 881 | MODULE_DESCRIPTION(ILO_NAME); |
| 765 | MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>"); | 882 | MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>"); |
diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h index 03a14c82aad9..38576050776a 100644 --- a/drivers/misc/hpilo.h +++ b/drivers/misc/hpilo.h | |||
| @@ -46,11 +46,14 @@ struct ilo_hwinfo { | |||
| 46 | 46 | ||
| 47 | spinlock_t alloc_lock; | 47 | spinlock_t alloc_lock; |
| 48 | spinlock_t fifo_lock; | 48 | spinlock_t fifo_lock; |
| 49 | spinlock_t open_lock; | ||
| 49 | 50 | ||
| 50 | struct cdev cdev; | 51 | struct cdev cdev; |
| 51 | }; | 52 | }; |
| 52 | 53 | ||
| 53 | /* offset from mmio_vaddr */ | 54 | /* offset from mmio_vaddr for enabling doorbell interrupts */ |
| 55 | #define DB_IRQ 0xB2 | ||
| 56 | /* offset from mmio_vaddr for outbound communications */ | ||
| 54 | #define DB_OUT 0xD4 | 57 | #define DB_OUT 0xD4 |
| 55 | /* DB_OUT reset bit */ | 58 | /* DB_OUT reset bit */ |
| 56 | #define DB_RESET 26 | 59 | #define DB_RESET 26 |
| @@ -131,6 +134,9 @@ struct ccb_data { | |||
| 131 | /* pointer to hardware device info */ | 134 | /* pointer to hardware device info */ |
| 132 | struct ilo_hwinfo *ilo_hw; | 135 | struct ilo_hwinfo *ilo_hw; |
| 133 | 136 | ||
| 137 | /* queue for this ccb to wait for recv data */ | ||
| 138 | wait_queue_head_t ccb_waitq; | ||
| 139 | |||
| 134 | /* usage count, to allow for shared ccb's */ | 140 | /* usage count, to allow for shared ccb's */ |
| 135 | int ccb_cnt; | 141 | int ccb_cnt; |
| 136 | 142 | ||
diff --git a/drivers/misc/ibmasm/command.c b/drivers/misc/ibmasm/command.c index 276d3fb68094..e2031739aa29 100644 --- a/drivers/misc/ibmasm/command.c +++ b/drivers/misc/ibmasm/command.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | * | 22 | * |
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #include <linux/sched.h> | ||
| 25 | #include "ibmasm.h" | 26 | #include "ibmasm.h" |
| 26 | #include "lowlevel.h" | 27 | #include "lowlevel.h" |
| 27 | 28 | ||
diff --git a/drivers/misc/ibmasm/event.c b/drivers/misc/ibmasm/event.c index 68a0a5b94795..572d41ffc186 100644 --- a/drivers/misc/ibmasm/event.c +++ b/drivers/misc/ibmasm/event.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | * | 22 | * |
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #include <linux/sched.h> | ||
| 25 | #include "ibmasm.h" | 26 | #include "ibmasm.h" |
| 26 | #include "lowlevel.h" | 27 | #include "lowlevel.h" |
| 27 | 28 | ||
diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c index de966a6fb7e6..aecf40ecb3a4 100644 --- a/drivers/misc/ibmasm/ibmasmfs.c +++ b/drivers/misc/ibmasm/ibmasmfs.c | |||
| @@ -97,7 +97,7 @@ static int ibmasmfs_get_super(struct file_system_type *fst, | |||
| 97 | return get_sb_single(fst, flags, data, ibmasmfs_fill_super, mnt); | 97 | return get_sb_single(fst, flags, data, ibmasmfs_fill_super, mnt); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | static struct super_operations ibmasmfs_s_ops = { | 100 | static const struct super_operations ibmasmfs_s_ops = { |
| 101 | .statfs = simple_statfs, | 101 | .statfs = simple_statfs, |
| 102 | .drop_inode = generic_delete_inode, | 102 | .drop_inode = generic_delete_inode, |
| 103 | }; | 103 | }; |
diff --git a/drivers/misc/ibmasm/r_heartbeat.c b/drivers/misc/ibmasm/r_heartbeat.c index bec9e2c44bef..2de487ac788c 100644 --- a/drivers/misc/ibmasm/r_heartbeat.c +++ b/drivers/misc/ibmasm/r_heartbeat.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | * | 20 | * |
| 21 | */ | 21 | */ |
| 22 | 22 | ||
| 23 | #include <linux/sched.h> | ||
| 23 | #include "ibmasm.h" | 24 | #include "ibmasm.h" |
| 24 | #include "dot_command.h" | 25 | #include "dot_command.h" |
| 25 | 26 | ||
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index 1bfe5d16963b..3648b23d5c92 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c | |||
| @@ -283,7 +283,7 @@ static int __init lkdtm_module_init(void) | |||
| 283 | 283 | ||
| 284 | switch (cpoint) { | 284 | switch (cpoint) { |
| 285 | case INT_HARDWARE_ENTRY: | 285 | case INT_HARDWARE_ENTRY: |
| 286 | lkdtm.kp.symbol_name = "__do_IRQ"; | 286 | lkdtm.kp.symbol_name = "do_IRQ"; |
| 287 | lkdtm.entry = (kprobe_opcode_t*) jp_do_irq; | 287 | lkdtm.entry = (kprobe_opcode_t*) jp_do_irq; |
| 288 | break; | 288 | break; |
| 289 | case INT_HW_IRQ_EN: | 289 | case INT_HW_IRQ_EN: |
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c index fa57b67593ae..04c27266f567 100644 --- a/drivers/misc/phantom.c +++ b/drivers/misc/phantom.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
| 23 | #include <linux/cdev.h> | 23 | #include <linux/cdev.h> |
| 24 | #include <linux/phantom.h> | 24 | #include <linux/phantom.h> |
| 25 | #include <linux/sched.h> | ||
| 25 | #include <linux/smp_lock.h> | 26 | #include <linux/smp_lock.h> |
| 26 | 27 | ||
| 27 | #include <asm/atomic.h> | 28 | #include <asm/atomic.h> |
| @@ -271,7 +272,7 @@ static unsigned int phantom_poll(struct file *file, poll_table *wait) | |||
| 271 | return mask; | 272 | return mask; |
| 272 | } | 273 | } |
| 273 | 274 | ||
| 274 | static struct file_operations phantom_file_ops = { | 275 | static const struct file_operations phantom_file_ops = { |
| 275 | .open = phantom_open, | 276 | .open = phantom_open, |
| 276 | .release = phantom_release, | 277 | .release = phantom_release, |
| 277 | .unlocked_ioctl = phantom_ioctl, | 278 | .unlocked_ioctl = phantom_ioctl, |
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c index aed609832bc2..41c8fe2a928c 100644 --- a/drivers/misc/sgi-gru/grufile.c +++ b/drivers/misc/sgi-gru/grufile.c | |||
| @@ -53,7 +53,6 @@ struct gru_stats_s gru_stats; | |||
| 53 | /* Guaranteed user available resources on each node */ | 53 | /* Guaranteed user available resources on each node */ |
| 54 | static int max_user_cbrs, max_user_dsr_bytes; | 54 | static int max_user_cbrs, max_user_dsr_bytes; |
| 55 | 55 | ||
| 56 | static struct file_operations gru_fops; | ||
| 57 | static struct miscdevice gru_miscdev; | 56 | static struct miscdevice gru_miscdev; |
| 58 | 57 | ||
| 59 | 58 | ||
| @@ -426,7 +425,7 @@ static void __exit gru_exit(void) | |||
| 426 | gru_proc_exit(); | 425 | gru_proc_exit(); |
| 427 | } | 426 | } |
| 428 | 427 | ||
| 429 | static struct file_operations gru_fops = { | 428 | static const struct file_operations gru_fops = { |
| 430 | .owner = THIS_MODULE, | 429 | .owner = THIS_MODULE, |
| 431 | .unlocked_ioctl = gru_file_unlocked_ioctl, | 430 | .unlocked_ioctl = gru_file_unlocked_ioctl, |
| 432 | .mmap = gru_file_mmap, | 431 | .mmap = gru_file_mmap, |
| @@ -438,7 +437,7 @@ static struct miscdevice gru_miscdev = { | |||
| 438 | .fops = &gru_fops, | 437 | .fops = &gru_fops, |
| 439 | }; | 438 | }; |
| 440 | 439 | ||
| 441 | struct vm_operations_struct gru_vm_ops = { | 440 | const struct vm_operations_struct gru_vm_ops = { |
| 442 | .close = gru_vma_close, | 441 | .close = gru_vma_close, |
| 443 | .fault = gru_fault, | 442 | .fault = gru_fault, |
| 444 | }; | 443 | }; |
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c index 79689b10f937..766e21e15574 100644 --- a/drivers/misc/sgi-gru/grukservices.c +++ b/drivers/misc/sgi-gru/grukservices.c | |||
| @@ -937,6 +937,8 @@ static int quicktest1(unsigned long arg) | |||
| 937 | 937 | ||
| 938 | /* Need 1K cacheline aligned that does not cross page boundary */ | 938 | /* Need 1K cacheline aligned that does not cross page boundary */ |
| 939 | p = kmalloc(4096, 0); | 939 | p = kmalloc(4096, 0); |
| 940 | if (p == NULL) | ||
| 941 | return -ENOMEM; | ||
| 940 | mq = ALIGNUP(p, 1024); | 942 | mq = ALIGNUP(p, 1024); |
| 941 | memset(mes, 0xee, sizeof(mes)); | 943 | memset(mes, 0xee, sizeof(mes)); |
| 942 | dw = mq; | 944 | dw = mq; |
diff --git a/drivers/misc/sgi-gru/gruprocfs.c b/drivers/misc/sgi-gru/gruprocfs.c index 9cbf95bedce6..ccd4408a26c7 100644 --- a/drivers/misc/sgi-gru/gruprocfs.c +++ b/drivers/misc/sgi-gru/gruprocfs.c | |||
| @@ -340,10 +340,9 @@ static struct proc_dir_entry *proc_gru __read_mostly; | |||
| 340 | 340 | ||
| 341 | static int create_proc_file(struct proc_entry *p) | 341 | static int create_proc_file(struct proc_entry *p) |
| 342 | { | 342 | { |
| 343 | p->entry = create_proc_entry(p->name, p->mode, proc_gru); | 343 | p->entry = proc_create(p->name, p->mode, proc_gru, p->fops); |
| 344 | if (!p->entry) | 344 | if (!p->entry) |
| 345 | return -1; | 345 | return -1; |
| 346 | p->entry->proc_fops = p->fops; | ||
| 347 | return 0; | 346 | return 0; |
| 348 | } | 347 | } |
| 349 | 348 | ||
diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h index 34ab3d453919..46990bcfa536 100644 --- a/drivers/misc/sgi-gru/grutables.h +++ b/drivers/misc/sgi-gru/grutables.h | |||
| @@ -624,7 +624,7 @@ static inline int is_kernel_context(struct gru_thread_state *gts) | |||
| 624 | */ | 624 | */ |
| 625 | struct gru_unload_context_req; | 625 | struct gru_unload_context_req; |
| 626 | 626 | ||
| 627 | extern struct vm_operations_struct gru_vm_ops; | 627 | extern const struct vm_operations_struct gru_vm_ops; |
| 628 | extern struct device *grudev; | 628 | extern struct device *grudev; |
| 629 | 629 | ||
| 630 | extern struct gru_vma_data *gru_alloc_vma_data(struct vm_area_struct *vma, | 630 | extern struct gru_vma_data *gru_alloc_vma_data(struct vm_area_struct *vma, |
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c index 915a3b495da5..8b70e03f939f 100644 --- a/drivers/misc/sgi-xp/xpc_sn2.c +++ b/drivers/misc/sgi-xp/xpc_sn2.c | |||
| @@ -279,7 +279,7 @@ xpc_check_for_sent_chctl_flags_sn2(struct xpc_partition *part) | |||
| 279 | spin_unlock_irqrestore(&part->chctl_lock, irq_flags); | 279 | spin_unlock_irqrestore(&part->chctl_lock, irq_flags); |
| 280 | 280 | ||
| 281 | dev_dbg(xpc_chan, "received notify IRQ from partid=%d, chctl.all_flags=" | 281 | dev_dbg(xpc_chan, "received notify IRQ from partid=%d, chctl.all_flags=" |
| 282 | "0x%lx\n", XPC_PARTID(part), chctl.all_flags); | 282 | "0x%llx\n", XPC_PARTID(part), chctl.all_flags); |
| 283 | 283 | ||
| 284 | xpc_wakeup_channel_mgr(part); | 284 | xpc_wakeup_channel_mgr(part); |
| 285 | } | 285 | } |
| @@ -615,7 +615,8 @@ xpc_get_partition_rsvd_page_pa_sn2(void *buf, u64 *cookie, unsigned long *rp_pa, | |||
| 615 | s64 status; | 615 | s64 status; |
| 616 | enum xp_retval ret; | 616 | enum xp_retval ret; |
| 617 | 617 | ||
| 618 | status = sn_partition_reserved_page_pa((u64)buf, cookie, rp_pa, len); | 618 | status = sn_partition_reserved_page_pa((u64)buf, cookie, |
| 619 | (u64 *)rp_pa, (u64 *)len); | ||
| 619 | if (status == SALRET_OK) | 620 | if (status == SALRET_OK) |
| 620 | ret = xpSuccess; | 621 | ret = xpSuccess; |
| 621 | else if (status == SALRET_MORE_PASSES) | 622 | else if (status == SALRET_MORE_PASSES) |
| @@ -777,8 +778,8 @@ xpc_get_remote_heartbeat_sn2(struct xpc_partition *part) | |||
| 777 | if (ret != xpSuccess) | 778 | if (ret != xpSuccess) |
| 778 | return ret; | 779 | return ret; |
| 779 | 780 | ||
| 780 | dev_dbg(xpc_part, "partid=%d, heartbeat=%ld, last_heartbeat=%ld, " | 781 | dev_dbg(xpc_part, "partid=%d, heartbeat=%lld, last_heartbeat=%lld, " |
| 781 | "heartbeat_offline=%ld, HB_mask[0]=0x%lx\n", XPC_PARTID(part), | 782 | "heartbeat_offline=%lld, HB_mask[0]=0x%lx\n", XPC_PARTID(part), |
| 782 | remote_vars->heartbeat, part->last_heartbeat, | 783 | remote_vars->heartbeat, part->last_heartbeat, |
| 783 | remote_vars->heartbeat_offline, | 784 | remote_vars->heartbeat_offline, |
| 784 | remote_vars->heartbeating_to_mask[0]); | 785 | remote_vars->heartbeating_to_mask[0]); |
| @@ -940,7 +941,7 @@ xpc_update_partition_info_sn2(struct xpc_partition *part, u8 remote_rp_version, | |||
| 940 | part_sn2->remote_vars_pa); | 941 | part_sn2->remote_vars_pa); |
| 941 | 942 | ||
| 942 | part->last_heartbeat = remote_vars->heartbeat - 1; | 943 | part->last_heartbeat = remote_vars->heartbeat - 1; |
| 943 | dev_dbg(xpc_part, " last_heartbeat = 0x%016lx\n", | 944 | dev_dbg(xpc_part, " last_heartbeat = 0x%016llx\n", |
| 944 | part->last_heartbeat); | 945 | part->last_heartbeat); |
| 945 | 946 | ||
| 946 | part_sn2->remote_vars_part_pa = remote_vars->vars_part_pa; | 947 | part_sn2->remote_vars_part_pa = remote_vars->vars_part_pa; |
| @@ -1029,7 +1030,8 @@ xpc_identify_activate_IRQ_req_sn2(int nasid) | |||
| 1029 | part->activate_IRQ_rcvd++; | 1030 | part->activate_IRQ_rcvd++; |
| 1030 | 1031 | ||
| 1031 | dev_dbg(xpc_part, "partid for nasid %d is %d; IRQs = %d; HB = " | 1032 | dev_dbg(xpc_part, "partid for nasid %d is %d; IRQs = %d; HB = " |
| 1032 | "%ld:0x%lx\n", (int)nasid, (int)partid, part->activate_IRQ_rcvd, | 1033 | "%lld:0x%lx\n", (int)nasid, (int)partid, |
| 1034 | part->activate_IRQ_rcvd, | ||
| 1033 | remote_vars->heartbeat, remote_vars->heartbeating_to_mask[0]); | 1035 | remote_vars->heartbeat, remote_vars->heartbeating_to_mask[0]); |
| 1034 | 1036 | ||
| 1035 | if (xpc_partition_disengaged(part) && | 1037 | if (xpc_partition_disengaged(part) && |
| @@ -1129,7 +1131,7 @@ xpc_identify_activate_IRQ_sender_sn2(void) | |||
| 1129 | do { | 1131 | do { |
| 1130 | n_IRQs_detected++; | 1132 | n_IRQs_detected++; |
| 1131 | nasid = (l * BITS_PER_LONG + b) * 2; | 1133 | nasid = (l * BITS_PER_LONG + b) * 2; |
| 1132 | dev_dbg(xpc_part, "interrupt from nasid %ld\n", nasid); | 1134 | dev_dbg(xpc_part, "interrupt from nasid %lld\n", nasid); |
| 1133 | xpc_identify_activate_IRQ_req_sn2(nasid); | 1135 | xpc_identify_activate_IRQ_req_sn2(nasid); |
| 1134 | 1136 | ||
| 1135 | b = find_next_bit(&nasid_mask_long, BITS_PER_LONG, | 1137 | b = find_next_bit(&nasid_mask_long, BITS_PER_LONG, |
| @@ -1386,7 +1388,7 @@ xpc_pull_remote_vars_part_sn2(struct xpc_partition *part) | |||
| 1386 | 1388 | ||
| 1387 | if (pulled_entry->magic != 0) { | 1389 | if (pulled_entry->magic != 0) { |
| 1388 | dev_dbg(xpc_chan, "partition %d's XPC vars_part for " | 1390 | dev_dbg(xpc_chan, "partition %d's XPC vars_part for " |
| 1389 | "partition %d has bad magic value (=0x%lx)\n", | 1391 | "partition %d has bad magic value (=0x%llx)\n", |
| 1390 | partid, sn_partition_id, pulled_entry->magic); | 1392 | partid, sn_partition_id, pulled_entry->magic); |
| 1391 | return xpBadMagic; | 1393 | return xpBadMagic; |
| 1392 | } | 1394 | } |
| @@ -1730,14 +1732,14 @@ xpc_notify_senders_sn2(struct xpc_channel *ch, enum xp_retval reason, s64 put) | |||
| 1730 | 1732 | ||
| 1731 | if (notify->func != NULL) { | 1733 | if (notify->func != NULL) { |
| 1732 | dev_dbg(xpc_chan, "notify->func() called, notify=0x%p " | 1734 | dev_dbg(xpc_chan, "notify->func() called, notify=0x%p " |
| 1733 | "msg_number=%ld partid=%d channel=%d\n", | 1735 | "msg_number=%lld partid=%d channel=%d\n", |
| 1734 | (void *)notify, get, ch->partid, ch->number); | 1736 | (void *)notify, get, ch->partid, ch->number); |
| 1735 | 1737 | ||
| 1736 | notify->func(reason, ch->partid, ch->number, | 1738 | notify->func(reason, ch->partid, ch->number, |
| 1737 | notify->key); | 1739 | notify->key); |
| 1738 | 1740 | ||
| 1739 | dev_dbg(xpc_chan, "notify->func() returned, notify=0x%p" | 1741 | dev_dbg(xpc_chan, "notify->func() returned, notify=0x%p" |
| 1740 | " msg_number=%ld partid=%d channel=%d\n", | 1742 | " msg_number=%lld partid=%d channel=%d\n", |
| 1741 | (void *)notify, get, ch->partid, ch->number); | 1743 | (void *)notify, get, ch->partid, ch->number); |
| 1742 | } | 1744 | } |
| 1743 | } | 1745 | } |
| @@ -1858,7 +1860,7 @@ xpc_process_msg_chctl_flags_sn2(struct xpc_partition *part, int ch_number) | |||
| 1858 | 1860 | ||
| 1859 | ch_sn2->w_remote_GP.get = ch_sn2->remote_GP.get; | 1861 | ch_sn2->w_remote_GP.get = ch_sn2->remote_GP.get; |
| 1860 | 1862 | ||
| 1861 | dev_dbg(xpc_chan, "w_remote_GP.get changed to %ld, partid=%d, " | 1863 | dev_dbg(xpc_chan, "w_remote_GP.get changed to %lld, partid=%d, " |
| 1862 | "channel=%d\n", ch_sn2->w_remote_GP.get, ch->partid, | 1864 | "channel=%d\n", ch_sn2->w_remote_GP.get, ch->partid, |
| 1863 | ch->number); | 1865 | ch->number); |
| 1864 | 1866 | ||
| @@ -1885,7 +1887,7 @@ xpc_process_msg_chctl_flags_sn2(struct xpc_partition *part, int ch_number) | |||
| 1885 | smp_wmb(); /* ensure flags have been cleared before bte_copy */ | 1887 | smp_wmb(); /* ensure flags have been cleared before bte_copy */ |
| 1886 | ch_sn2->w_remote_GP.put = ch_sn2->remote_GP.put; | 1888 | ch_sn2->w_remote_GP.put = ch_sn2->remote_GP.put; |
| 1887 | 1889 | ||
| 1888 | dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, " | 1890 | dev_dbg(xpc_chan, "w_remote_GP.put changed to %lld, partid=%d, " |
| 1889 | "channel=%d\n", ch_sn2->w_remote_GP.put, ch->partid, | 1891 | "channel=%d\n", ch_sn2->w_remote_GP.put, ch->partid, |
| 1890 | ch->number); | 1892 | ch->number); |
| 1891 | 1893 | ||
| @@ -1943,7 +1945,7 @@ xpc_pull_remote_msg_sn2(struct xpc_channel *ch, s64 get) | |||
| 1943 | if (ret != xpSuccess) { | 1945 | if (ret != xpSuccess) { |
| 1944 | 1946 | ||
| 1945 | dev_dbg(xpc_chan, "failed to pull %d msgs starting with" | 1947 | dev_dbg(xpc_chan, "failed to pull %d msgs starting with" |
| 1946 | " msg %ld from partition %d, channel=%d, " | 1948 | " msg %lld from partition %d, channel=%d, " |
| 1947 | "ret=%d\n", nmsgs, ch_sn2->next_msg_to_pull, | 1949 | "ret=%d\n", nmsgs, ch_sn2->next_msg_to_pull, |
| 1948 | ch->partid, ch->number, ret); | 1950 | ch->partid, ch->number, ret); |
| 1949 | 1951 | ||
| @@ -1995,7 +1997,7 @@ xpc_get_deliverable_payload_sn2(struct xpc_channel *ch) | |||
| 1995 | if (cmpxchg(&ch_sn2->w_local_GP.get, get, get + 1) == get) { | 1997 | if (cmpxchg(&ch_sn2->w_local_GP.get, get, get + 1) == get) { |
| 1996 | /* we got the entry referenced by get */ | 1998 | /* we got the entry referenced by get */ |
| 1997 | 1999 | ||
| 1998 | dev_dbg(xpc_chan, "w_local_GP.get changed to %ld, " | 2000 | dev_dbg(xpc_chan, "w_local_GP.get changed to %lld, " |
| 1999 | "partid=%d, channel=%d\n", get + 1, | 2001 | "partid=%d, channel=%d\n", get + 1, |
| 2000 | ch->partid, ch->number); | 2002 | ch->partid, ch->number); |
| 2001 | 2003 | ||
| @@ -2062,7 +2064,7 @@ xpc_send_msgs_sn2(struct xpc_channel *ch, s64 initial_put) | |||
| 2062 | 2064 | ||
| 2063 | /* we just set the new value of local_GP->put */ | 2065 | /* we just set the new value of local_GP->put */ |
| 2064 | 2066 | ||
| 2065 | dev_dbg(xpc_chan, "local_GP->put changed to %ld, partid=%d, " | 2067 | dev_dbg(xpc_chan, "local_GP->put changed to %lld, partid=%d, " |
| 2066 | "channel=%d\n", put, ch->partid, ch->number); | 2068 | "channel=%d\n", put, ch->partid, ch->number); |
| 2067 | 2069 | ||
| 2068 | send_msgrequest = 1; | 2070 | send_msgrequest = 1; |
| @@ -2147,8 +2149,8 @@ xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags, | |||
| 2147 | DBUG_ON(msg->flags != 0); | 2149 | DBUG_ON(msg->flags != 0); |
| 2148 | msg->number = put; | 2150 | msg->number = put; |
| 2149 | 2151 | ||
| 2150 | dev_dbg(xpc_chan, "w_local_GP.put changed to %ld; msg=0x%p, " | 2152 | dev_dbg(xpc_chan, "w_local_GP.put changed to %lld; msg=0x%p, " |
| 2151 | "msg_number=%ld, partid=%d, channel=%d\n", put + 1, | 2153 | "msg_number=%lld, partid=%d, channel=%d\n", put + 1, |
| 2152 | (void *)msg, msg->number, ch->partid, ch->number); | 2154 | (void *)msg, msg->number, ch->partid, ch->number); |
| 2153 | 2155 | ||
| 2154 | *address_of_msg = msg; | 2156 | *address_of_msg = msg; |
| @@ -2296,7 +2298,7 @@ xpc_acknowledge_msgs_sn2(struct xpc_channel *ch, s64 initial_get, u8 msg_flags) | |||
| 2296 | 2298 | ||
| 2297 | /* we just set the new value of local_GP->get */ | 2299 | /* we just set the new value of local_GP->get */ |
| 2298 | 2300 | ||
| 2299 | dev_dbg(xpc_chan, "local_GP->get changed to %ld, partid=%d, " | 2301 | dev_dbg(xpc_chan, "local_GP->get changed to %lld, partid=%d, " |
| 2300 | "channel=%d\n", get, ch->partid, ch->number); | 2302 | "channel=%d\n", get, ch->partid, ch->number); |
| 2301 | 2303 | ||
| 2302 | send_msgrequest = (msg_flags & XPC_M_SN2_INTERRUPT); | 2304 | send_msgrequest = (msg_flags & XPC_M_SN2_INTERRUPT); |
| @@ -2323,7 +2325,7 @@ xpc_received_payload_sn2(struct xpc_channel *ch, void *payload) | |||
| 2323 | msg = container_of(payload, struct xpc_msg_sn2, payload); | 2325 | msg = container_of(payload, struct xpc_msg_sn2, payload); |
| 2324 | msg_number = msg->number; | 2326 | msg_number = msg->number; |
| 2325 | 2327 | ||
| 2326 | dev_dbg(xpc_chan, "msg=0x%p, msg_number=%ld, partid=%d, channel=%d\n", | 2328 | dev_dbg(xpc_chan, "msg=0x%p, msg_number=%lld, partid=%d, channel=%d\n", |
| 2327 | (void *)msg, msg_number, ch->partid, ch->number); | 2329 | (void *)msg, msg_number, ch->partid, ch->number); |
| 2328 | 2330 | ||
| 2329 | DBUG_ON((((u64)msg - (u64)ch->sn.sn2.remote_msgqueue) / ch->entry_size) != | 2331 | DBUG_ON((((u64)msg - (u64)ch->sn.sn2.remote_msgqueue) / ch->entry_size) != |
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c index 5d778ec8cdb2..16f0abda1423 100644 --- a/drivers/misc/sgi-xp/xpnet.c +++ b/drivers/misc/sgi-xp/xpnet.c | |||
| @@ -240,7 +240,6 @@ xpnet_receive(short partid, int channel, struct xpnet_message *msg) | |||
| 240 | (void *)skb->head, (void *)skb->data, skb_tail_pointer(skb), | 240 | (void *)skb->head, (void *)skb->data, skb_tail_pointer(skb), |
| 241 | skb_end_pointer(skb), skb->len); | 241 | skb_end_pointer(skb), skb->len); |
| 242 | 242 | ||
| 243 | xpnet_device->last_rx = jiffies; | ||
| 244 | xpnet_device->stats.rx_packets++; | 243 | xpnet_device->stats.rx_packets++; |
| 245 | xpnet_device->stats.rx_bytes += skb->len + ETH_HLEN; | 244 | xpnet_device->stats.rx_bytes += skb->len + ETH_HLEN; |
| 246 | 245 | ||
| @@ -436,7 +435,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 436 | 435 | ||
| 437 | if (skb->data[0] == 0x33) { | 436 | if (skb->data[0] == 0x33) { |
| 438 | dev_kfree_skb(skb); | 437 | dev_kfree_skb(skb); |
| 439 | return 0; /* nothing needed to be done */ | 438 | return NETDEV_TX_OK; /* nothing needed to be done */ |
| 440 | } | 439 | } |
| 441 | 440 | ||
| 442 | /* | 441 | /* |
| @@ -503,7 +502,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 503 | dev->stats.tx_packets++; | 502 | dev->stats.tx_packets++; |
| 504 | dev->stats.tx_bytes += skb->len; | 503 | dev->stats.tx_bytes += skb->len; |
| 505 | 504 | ||
| 506 | return 0; | 505 | return NETDEV_TX_OK; |
| 507 | } | 506 | } |
| 508 | 507 | ||
| 509 | /* | 508 | /* |
