Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input updates from Dmitry Torokhov:

 - a new driver for Rohm BU21029 touch controller

 - new bitmap APIs: bitmap_alloc, bitmap_zalloc and bitmap_free

 - updates to Atmel, eeti. pxrc and iforce drivers

 - assorted driver cleanups and fixes.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (57 commits)
  MAINTAINERS: Add PhoenixRC Flight Controller Adapter
  Input: do not use WARN() in input_alloc_absinfo()
  Input: mark expected switch fall-throughs
  Input: raydium_i2c_ts - use true and false for boolean values
  Input: evdev - switch to bitmap API
  Input: gpio-keys - switch to bitmap_zalloc()
  Input: elan_i2c_smbus - cast sizeof to int for comparison
  bitmap: Add bitmap_alloc(), bitmap_zalloc() and bitmap_free()
  md: Avoid namespace collision with bitmap API
  dm: Avoid namespace collision with bitmap API
  Input: pm8941-pwrkey - add resin entry
  Input: pm8941-pwrkey - abstract register offsets and event code
  Input: iforce - reorganize joystick configuration lists
  Input: atmel_mxt_ts - move completion to after config crc is updated
  Input: atmel_mxt_ts - don't report zero pressure from T9
  Input: atmel_mxt_ts - zero terminate config firmware file
  Input: atmel_mxt_ts - refactor config update code to add context struct
  Input: atmel_mxt_ts - config CRC may start at T71
  Input: atmel_mxt_ts - remove unnecessary debug on ENOMEM
  Input: atmel_mxt_ts - remove duplicate setup of ABS_MT_PRESSURE
  ...
This commit is contained in:
Linus Torvalds 2018-08-18 16:48:07 -07:00
commit 08b5fa8199
99 changed files with 1472 additions and 971 deletions

View File

@ -0,0 +1,8 @@
General Keys Properties:
Optional properties for Keys:
- power-off-time-sec: Duration in seconds which the key should be kept
pressed for device to power off automatically. Device with key pressed
shutdown feature can specify this property.
- linux,keycodes: Specifies the numeric keycode values to be used for
reporting key presses.

View File

@ -7,6 +7,7 @@ PROPERTIES
Value type: <string>
Definition: must be one of:
"qcom,pm8941-pwrkey"
"qcom,pm8941-resin"
- reg:
Usage: required
@ -32,6 +33,14 @@ PROPERTIES
Definition: presence of this property indicates that the KPDPWR_N pin
should be configured for pull up.
- linux,code:
Usage: optional
Value type: <u32>
Definition: The input key-code associated with the power key.
Use the linux event codes defined in
include/dt-bindings/input/linux-event-codes.h
When property is omitted KEY_POWER is assumed.
EXAMPLE
pwrkey@800 {
@ -40,4 +49,5 @@ EXAMPLE
interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
debounce = <15625>;
bias-pull-up;
linux,code = <KEY_POWER>;
};

View File

@ -0,0 +1,35 @@
* Rohm BU21029 Touch Screen Controller
Required properties:
- compatible : must be "rohm,bu21029"
- reg : i2c device address of the chip (0x40 or 0x41)
- interrupt-parent : the phandle for the gpio controller
- interrupts : (gpio) interrupt to which the chip is connected
- rohm,x-plate-ohms : x-plate resistance in Ohm
Optional properties:
- reset-gpios : gpio pin to reset the chip (active low)
- touchscreen-size-x : horizontal resolution of touchscreen (in pixels)
- touchscreen-size-y : vertical resolution of touchscreen (in pixels)
- touchscreen-max-pressure: maximum pressure value
- vdd-supply : power supply for the controller
Example:
&i2c1 {
/* ... */
bu21029: bu21029@40 {
compatible = "rohm,bu21029";
reg = <0x40>;
interrupt-parent = <&gpio1>;
interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
reset-gpios = <&gpio6 16 GPIO_ACTIVE_LOW>;
rohm,x-plate-ohms = <600>;
touchscreen-size-x = <800>;
touchscreen-size-y = <480>;
touchscreen-max-pressure = <4095>;
};
/* ... */
};

View File

@ -0,0 +1,30 @@
Bindings for EETI touchscreen controller
Required properties:
- compatible: should be "eeti,exc3000-i2c"
- reg: I2C address of the chip. Should be set to <0xa>
- interrupts: interrupt to which the chip is connected
Optional properties:
- attn-gpios: A handle to a GPIO to check whether interrupt is still
latched. This is necessary for platforms that lack
support for level-triggered IRQs.
The following optional properties described in touchscreen.txt are
also supported:
- touchscreen-inverted-x
- touchscreen-inverted-y
- touchscreen-swapped-x-y
Example:
i2c-master {
touchscreen@a {
compatible = "eeti,exc3000-i2c";
reg = <0xa>;
interrupt-parent = <&gpio>;
interrupts = <123 IRQ_TYPE_EDGE_RISING>;
attn-gpios = <&gpio 123 GPIO_ACTIVE_HIGH>;
};
};

View File

@ -11340,6 +11340,13 @@ S: Maintained
F: include/linux/personality.h
F: include/uapi/linux/personality.h
PHOENIX RC FLIGHT CONTROLLER ADAPTER
M: Marcus Folkesson <marcus.folkesson@gmail.com>
L: linux-input@vger.kernel.org
S: Maintained
F: Documentation/input/devices/pxrc.rst
F: drivers/input/joystick/pxrc.c
PHONET PROTOCOL
M: Remi Denis-Courmont <courmisch@gmail.com>
S: Supported

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

View File

@ -481,7 +481,7 @@ static int evdev_release(struct inode *inode, struct file *file)
evdev_detach_client(evdev, client);
for (i = 0; i < EV_CNT; ++i)
kfree(client->evmasks[i]);
bitmap_free(client->evmasks[i]);
kvfree(client);
@ -925,17 +925,15 @@ static int evdev_handle_get_val(struct evdev_client *client,
{
int ret;
unsigned long *mem;
size_t len;
len = BITS_TO_LONGS(maxbit) * sizeof(unsigned long);
mem = kmalloc(len, GFP_KERNEL);
mem = bitmap_alloc(maxbit, GFP_KERNEL);
if (!mem)
return -ENOMEM;
spin_lock_irq(&dev->event_lock);
spin_lock(&client->buffer_lock);
memcpy(mem, bits, len);
bitmap_copy(mem, bits, maxbit);
spin_unlock(&dev->event_lock);
@ -947,7 +945,7 @@ static int evdev_handle_get_val(struct evdev_client *client,
if (ret < 0)
evdev_queue_syn_dropped(client);
kfree(mem);
bitmap_free(mem);
return ret;
}
@ -1003,13 +1001,13 @@ static int evdev_set_mask(struct evdev_client *client,
if (!cnt)
return 0;
mask = kcalloc(sizeof(unsigned long), BITS_TO_LONGS(cnt), GFP_KERNEL);
mask = bitmap_zalloc(cnt, GFP_KERNEL);
if (!mask)
return -ENOMEM;
error = bits_from_user(mask, cnt - 1, codes_size, codes, compat);
if (error < 0) {
kfree(mask);
bitmap_free(mask);
return error;
}
@ -1018,7 +1016,7 @@ static int evdev_set_mask(struct evdev_client *client,
client->evmasks[type] = mask;
spin_unlock_irqrestore(&client->buffer_lock, flags);
kfree(oldmask);
bitmap_free(oldmask);
return 0;
}

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <asm/io.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <asm/io.h>

View File

@ -21,10 +21,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <asm/io.h>

View File

@ -480,11 +480,19 @@ EXPORT_SYMBOL(input_inject_event);
*/
void input_alloc_absinfo(struct input_dev *dev)
{
if (!dev->absinfo)
dev->absinfo = kcalloc(ABS_CNT, sizeof(*dev->absinfo),
GFP_KERNEL);
if (dev->absinfo)
return;
WARN(!dev->absinfo, "%s(): kcalloc() failed?\n", __func__);
dev->absinfo = kcalloc(ABS_CNT, sizeof(*dev->absinfo), GFP_KERNEL);
if (!dev->absinfo) {
dev_err(dev->dev.parent ?: &dev->dev,
"%s: unable to allocate memory\n", __func__);
/*
* We will handle this allocation failure in
* input_register_device() when we refuse to register input
* device with ABS bits but without absinfo.
*/
}
}
EXPORT_SYMBOL(input_alloc_absinfo);

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/delay.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/types.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/delay.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>

View File

@ -23,10 +23,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>
@ -263,6 +259,7 @@ static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char
db9_saturn_write_sub(port, type, 3, powered, 0);
return data[0] = 0xe3;
}
/* else: fall through */
default:
return data[0];
}
@ -282,11 +279,14 @@ static int db9_saturn_report(unsigned char id, unsigned char data[60], struct in
switch (data[j]) {
case 0x16: /* multi controller (analog 4 axis) */
input_report_abs(dev, db9_abs[5], data[j + 6]);
/* fall through */
case 0x15: /* mission stick (analog 3 axis) */
input_report_abs(dev, db9_abs[3], data[j + 4]);
input_report_abs(dev, db9_abs[4], data[j + 5]);
/* fall through */
case 0x13: /* racing controller (analog 1 axis) */
input_report_abs(dev, db9_abs[2], data[j + 3]);
/* fall through */
case 0x34: /* saturn keyboard (udlr ZXC ASD QE Esc) */
case 0x02: /* digital pad (digital 2 axis + buttons) */
input_report_abs(dev, db9_abs[0], !(data[j + 1] & 128) - !(data[j + 1] & 64));
@ -380,6 +380,7 @@ static void db9_timer(struct timer_list *t)
input_report_abs(dev2, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
input_report_abs(dev2, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
input_report_key(dev2, BTN_TRIGGER, ~data & DB9_FIRE1);
/* fall through */
case DB9_MULTI_0802:

View File

@ -24,10 +24,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/delay.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>

View File

@ -19,10 +19,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include "iforce.h"
@ -56,7 +52,7 @@ static int make_magnitude_modifier(struct iforce* iforce,
iforce_send_packet(iforce, FF_CMD_MAGNITUDE, data);
iforce_dump_packet("magnitude: ", FF_CMD_MAGNITUDE, data);
iforce_dump_packet(iforce, "magnitude", FF_CMD_MAGNITUDE, data);
return 0;
}
@ -178,7 +174,7 @@ static int make_condition_modifier(struct iforce* iforce,
data[9] = (100 * lsat) >> 16;
iforce_send_packet(iforce, FF_CMD_CONDITION, data);
iforce_dump_packet("condition", FF_CMD_CONDITION, data);
iforce_dump_packet(iforce, "condition", FF_CMD_CONDITION, data);
return 0;
}

View File

@ -19,10 +19,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include "iforce.h"
@ -33,21 +29,14 @@ MODULE_LICENSE("GPL");
static signed short btn_joystick[] =
{ BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE,
BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A, BTN_B, BTN_C, -1 };
BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A,
BTN_B, BTN_C, BTN_DEAD, -1 };
static signed short btn_avb_pegasus[] =
{ BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE,
BTN_BASE2, BTN_BASE3, BTN_BASE4, -1 };
static signed short btn_joystick_avb[] =
{ BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE,
BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_DEAD, -1 };
static signed short btn_wheel[] =
{ BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE,
BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A, BTN_B, BTN_C, -1 };
static signed short btn_avb_tw[] =
{ BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE,
BTN_BASE2, BTN_BASE3, BTN_BASE4, -1 };
static signed short btn_avb_wheel[] =
{ BTN_GEAR_DOWN, BTN_GEAR_UP, BTN_BASE, BTN_BASE2, BTN_BASE3,
BTN_BASE4, BTN_BASE5, BTN_BASE6, -1 };
@ -73,9 +62,9 @@ static struct iforce_device iforce_device[] = {
{ 0x044f, 0xa01c, "Thrustmaster Motor Sport GT", btn_wheel, abs_wheel, ff_iforce },
{ 0x046d, 0xc281, "Logitech WingMan Force", btn_joystick, abs_joystick, ff_iforce },
{ 0x046d, 0xc291, "Logitech WingMan Formula Force", btn_wheel, abs_wheel, ff_iforce },
{ 0x05ef, 0x020a, "AVB Top Shot Pegasus", btn_avb_pegasus, abs_avb_pegasus, ff_iforce },
{ 0x05ef, 0x8884, "AVB Mag Turbo Force", btn_avb_wheel, abs_wheel, ff_iforce },
{ 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel", btn_avb_tw, abs_wheel, ff_iforce }, //?
{ 0x05ef, 0x020a, "AVB Top Shot Pegasus", btn_joystick_avb, abs_avb_pegasus, ff_iforce },
{ 0x05ef, 0x8884, "AVB Mag Turbo Force", btn_wheel, abs_wheel, ff_iforce },
{ 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //?
{ 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //?
{ 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce },
{ 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //?
@ -360,7 +349,7 @@ int iforce_init_device(struct iforce *iforce)
for (i = 0; c[i]; i++)
if (!iforce_get_id_packet(iforce, c + i))
iforce_dump_packet("info", iforce->ecmd, iforce->edata);
iforce_dump_packet(iforce, "info", iforce->ecmd, iforce->edata);
/*
* Disable spring, enable force feedback.
@ -388,7 +377,6 @@ int iforce_init_device(struct iforce *iforce)
for (i = 0; iforce->type->btn[i] >= 0; i++)
set_bit(iforce->type->btn[i], input_dev->keybit);
set_bit(BTN_DEAD, input_dev->keybit);
for (i = 0; iforce->type->abs[i] >= 0; i++) {

View File

@ -19,10 +19,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include "iforce.h"
@ -33,14 +29,10 @@ static struct {
} iforce_hat_to_axis[16] = {{ 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data)
void iforce_dump_packet(struct iforce *iforce, char *msg, u16 cmd, unsigned char *data)
{
int i;
printk(KERN_DEBUG __FILE__ ": %s cmd = %04x, data = ", msg, cmd);
for (i = 0; i < LO(cmd); i++)
printk("%02x ", data[i]);
printk("\n");
dev_dbg(iforce->dev->dev.parent, "%s %s cmd = %04x, data = %*ph\n",
__func__, msg, cmd, LO(cmd), data);
}
/*
@ -255,7 +247,7 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet)
iforce->cr.bRequest = packet[0];
iforce->ctrl->dev = iforce->usbdev;
status = usb_submit_urb(iforce->ctrl, GFP_ATOMIC);
status = usb_submit_urb(iforce->ctrl, GFP_KERNEL);
if (status) {
dev_err(&iforce->intf->dev,
"usb_submit_urb failed %d\n", status);

View File

@ -19,10 +19,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include "iforce.h"

View File

@ -19,10 +19,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include "iforce.h"

View File

@ -19,10 +19,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>
@ -158,7 +154,7 @@ int iforce_init_device(struct iforce *iforce);
int iforce_control_playback(struct iforce*, u16 id, unsigned int);
void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data);
int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data);
void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) ;
void iforce_dump_packet(struct iforce *iforce, char *msg, u16 cmd, unsigned char *data);
int iforce_get_id_packet(struct iforce *iforce, char *packet);
/* iforce-ff.c */

View File

@ -23,10 +23,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>

View File

@ -21,10 +21,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/module.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>

View File

@ -3,7 +3,6 @@
* Driver for Phoenix RC Flight Controller Adapter
*
* Copyright (C) 2018 Marcus Folkesson <marcus.folkesson@gmail.com>
*
*/
#include <linux/kernel.h>
@ -16,31 +15,22 @@
#include <linux/mutex.h>
#include <linux/input.h>
#define PXRC_VENDOR_ID (0x1781)
#define PXRC_PRODUCT_ID (0x0898)
static const struct usb_device_id pxrc_table[] = {
{ USB_DEVICE(PXRC_VENDOR_ID, PXRC_PRODUCT_ID) },
{ }
};
MODULE_DEVICE_TABLE(usb, pxrc_table);
#define PXRC_VENDOR_ID 0x1781
#define PXRC_PRODUCT_ID 0x0898
struct pxrc {
struct input_dev *input;
struct usb_device *udev;
struct usb_interface *intf;
struct urb *urb;
struct mutex pm_mutex;
bool is_open;
__u8 epaddr;
char phys[64];
unsigned char *data;
size_t bsize;
};
static void pxrc_usb_irq(struct urb *urb)
{
struct pxrc *pxrc = urb->context;
u8 *data = urb->transfer_buffer;
int error;
switch (urb->status) {
@ -68,15 +58,15 @@ static void pxrc_usb_irq(struct urb *urb)
}
if (urb->actual_length == 8) {
input_report_abs(pxrc->input, ABS_X, pxrc->data[0]);
input_report_abs(pxrc->input, ABS_Y, pxrc->data[2]);
input_report_abs(pxrc->input, ABS_RX, pxrc->data[3]);
input_report_abs(pxrc->input, ABS_RY, pxrc->data[4]);
input_report_abs(pxrc->input, ABS_RUDDER, pxrc->data[5]);
input_report_abs(pxrc->input, ABS_THROTTLE, pxrc->data[6]);
input_report_abs(pxrc->input, ABS_MISC, pxrc->data[7]);
input_report_abs(pxrc->input, ABS_X, data[0]);
input_report_abs(pxrc->input, ABS_Y, data[2]);
input_report_abs(pxrc->input, ABS_RX, data[3]);
input_report_abs(pxrc->input, ABS_RY, data[4]);
input_report_abs(pxrc->input, ABS_RUDDER, data[5]);
input_report_abs(pxrc->input, ABS_THROTTLE, data[6]);
input_report_abs(pxrc->input, ABS_MISC, data[7]);
input_report_key(pxrc->input, BTN_A, pxrc->data[1]);
input_report_key(pxrc->input, BTN_A, data[1]);
}
exit:
@ -120,61 +110,73 @@ static void pxrc_close(struct input_dev *input)
mutex_unlock(&pxrc->pm_mutex);
}
static int pxrc_usb_init(struct pxrc *pxrc)
static void pxrc_free_urb(void *_pxrc)
{
struct usb_endpoint_descriptor *epirq;
unsigned int pipe;
int retval;
/* Set up the endpoint information */
/* This device only has an interrupt endpoint */
retval = usb_find_common_endpoints(pxrc->intf->cur_altsetting,
NULL, NULL, &epirq, NULL);
if (retval) {
dev_err(&pxrc->intf->dev,
"Could not find endpoint\n");
goto error;
}
pxrc->bsize = usb_endpoint_maxp(epirq);
pxrc->epaddr = epirq->bEndpointAddress;
pxrc->data = devm_kmalloc(&pxrc->intf->dev, pxrc->bsize, GFP_KERNEL);
if (!pxrc->data) {
retval = -ENOMEM;
goto error;
}
usb_set_intfdata(pxrc->intf, pxrc);
usb_make_path(pxrc->udev, pxrc->phys, sizeof(pxrc->phys));
strlcat(pxrc->phys, "/input0", sizeof(pxrc->phys));
pxrc->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!pxrc->urb) {
retval = -ENOMEM;
goto error;
}
pipe = usb_rcvintpipe(pxrc->udev, pxrc->epaddr),
usb_fill_int_urb(pxrc->urb, pxrc->udev, pipe, pxrc->data, pxrc->bsize,
pxrc_usb_irq, pxrc, 1);
error:
return retval;
struct pxrc *pxrc = _pxrc;
usb_free_urb(pxrc->urb);
}
static int pxrc_input_init(struct pxrc *pxrc)
static int pxrc_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
pxrc->input = devm_input_allocate_device(&pxrc->intf->dev);
if (pxrc->input == NULL) {
dev_err(&pxrc->intf->dev, "couldn't allocate input device\n");
struct usb_device *udev = interface_to_usbdev(intf);
struct pxrc *pxrc;
struct usb_endpoint_descriptor *epirq;
size_t xfer_size;
void *xfer_buf;
int error;
/*
* Locate the endpoint information. This device only has an
* interrupt endpoint.
*/
error = usb_find_common_endpoints(intf->cur_altsetting,
NULL, NULL, &epirq, NULL);
if (error) {
dev_err(&intf->dev, "Could not find endpoint\n");
return error;
}
pxrc = devm_kzalloc(&intf->dev, sizeof(*pxrc), GFP_KERNEL);
if (!pxrc)
return -ENOMEM;
mutex_init(&pxrc->pm_mutex);
pxrc->intf = intf;
usb_set_intfdata(pxrc->intf, pxrc);
xfer_size = usb_endpoint_maxp(epirq);
xfer_buf = devm_kmalloc(&intf->dev, xfer_size, GFP_KERNEL);
if (!xfer_buf)
return -ENOMEM;
pxrc->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!pxrc->urb)
return -ENOMEM;
error = devm_add_action_or_reset(&intf->dev, pxrc_free_urb, pxrc);
if (error)
return error;
usb_fill_int_urb(pxrc->urb, udev,
usb_rcvintpipe(udev, epirq->bEndpointAddress),
xfer_buf, xfer_size, pxrc_usb_irq, pxrc, 1);
pxrc->input = devm_input_allocate_device(&intf->dev);
if (!pxrc->input) {
dev_err(&intf->dev, "couldn't allocate input device\n");
return -ENOMEM;
}
pxrc->input->name = "PXRC Flight Controller Adapter";
usb_make_path(udev, pxrc->phys, sizeof(pxrc->phys));
strlcat(pxrc->phys, "/input0", sizeof(pxrc->phys));
pxrc->input->phys = pxrc->phys;
usb_to_input_id(pxrc->udev, &pxrc->input->id);
usb_to_input_id(udev, &pxrc->input->id);
pxrc->input->open = pxrc_open;
pxrc->input->close = pxrc_close;
@ -190,46 +192,16 @@ static int pxrc_input_init(struct pxrc *pxrc)
input_set_drvdata(pxrc->input, pxrc);
return input_register_device(pxrc->input);
}
static int pxrc_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct pxrc *pxrc;
int retval;
pxrc = devm_kzalloc(&intf->dev, sizeof(*pxrc), GFP_KERNEL);
if (!pxrc)
return -ENOMEM;
mutex_init(&pxrc->pm_mutex);
pxrc->udev = usb_get_dev(interface_to_usbdev(intf));
pxrc->intf = intf;
retval = pxrc_usb_init(pxrc);
if (retval)
goto error;
retval = pxrc_input_init(pxrc);
if (retval)
goto err_free_urb;
error = input_register_device(pxrc->input);
if (error)
return error;
return 0;
err_free_urb:
usb_free_urb(pxrc->urb);
error:
return retval;
}
static void pxrc_disconnect(struct usb_interface *intf)
{
struct pxrc *pxrc = usb_get_intfdata(intf);
usb_free_urb(pxrc->urb);
usb_set_intfdata(intf, NULL);
/* All driver resources are devm-managed. */
}
static int pxrc_suspend(struct usb_interface *intf, pm_message_t message)
@ -284,6 +256,12 @@ static int pxrc_reset_resume(struct usb_interface *intf)
return pxrc_resume(intf);
}
static const struct usb_device_id pxrc_table[] = {
{ USB_DEVICE(PXRC_VENDOR_ID, PXRC_PRODUCT_ID) },
{ }
};
MODULE_DEVICE_TABLE(usb, pxrc_table);
static struct usb_driver pxrc_driver = {
.name = "pxrc",
.probe = pxrc_probe,

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/delay.h>

View File

@ -24,10 +24,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>

View File

@ -23,10 +23,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>

View File

@ -21,10 +21,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>

View File

@ -23,10 +23,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/delay.h>

View File

@ -23,10 +23,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/kernel.h>

View File

@ -885,6 +885,7 @@ static int adp5589_probe(struct i2c_client *client,
switch (id->driver_data) {
case ADP5585_02:
kpad->support_row5 = true;
/* fall through */
case ADP5585_01:
kpad->is_adp5585 = true;
kpad->var = &const_adp5585;

View File

@ -23,10 +23,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/module.h>

View File

@ -34,10 +34,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/module.h>

View File

@ -1,25 +1,15 @@
/*
* ChromeOS EC keyboard driver
*
* Copyright (C) 2012 Google, Inc
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This driver uses the Chrome OS EC byte-level message-based protocol for
* communicating the keyboard state (which keys are pressed) from a keyboard EC
* to the AP over some bus (such as i2c, lpc, spi). The EC does debouncing,
* but everything else (including deghosting) is done here. The main
* motivation for this is to keep the EC firmware as simple as possible, since
* it cannot be easily upgraded and EC flash/IRAM space is relatively
* expensive.
*/
// SPDX-License-Identifier: GPL-2.0
// ChromeOS EC keyboard driver
//
// Copyright (C) 2012 Google, Inc.
//
// This driver uses the ChromeOS EC byte-level message-based protocol for
// communicating the keyboard state (which keys are pressed) from a keyboard EC
// to the AP over some bus (such as i2c, lpc, spi). The EC does debouncing,
// but everything else (including deghosting) is done here. The main
// motivation for this is to keep the EC firmware as simple as possible, since
// it cannot be easily upgraded and EC flash/IRAM space is relatively
// expensive.
#include <linux/module.h>
#include <linux/bitops.h>
@ -170,9 +160,6 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
int col, row;
int new_state;
int old_state;
int num_cols;
num_cols = len;
if (ckdev->ghost_filter && cros_ec_keyb_has_ghosting(ckdev, kb_state)) {
/*
@ -242,19 +229,17 @@ static int cros_ec_keyb_work(struct notifier_block *nb,
u32 val;
unsigned int ev_type;
/*
* If not wake enabled, discard key state changes during
* suspend. Switches will be re-checked in
* cros_ec_keyb_resume() to be sure nothing is lost.
*/
if (queued_during_suspend && !device_may_wakeup(ckdev->dev))
return NOTIFY_OK;
switch (ckdev->ec->event_data.event_type) {
case EC_MKBP_EVENT_KEY_MATRIX:
if (device_may_wakeup(ckdev->dev)) {
pm_wakeup_event(ckdev->dev, 0);
} else {
/*
* If keyboard is not wake enabled, discard key state
* changes during suspend. Switches will be re-checked
* in cros_ec_keyb_resume() to be sure nothing is lost.
*/
if (queued_during_suspend)
return NOTIFY_OK;
}
pm_wakeup_event(ckdev->dev, 0);
if (ckdev->ec->event_size != ckdev->cols) {
dev_err(ckdev->dev,
@ -268,10 +253,7 @@ static int cros_ec_keyb_work(struct notifier_block *nb,
break;
case EC_MKBP_EVENT_SYSRQ:
if (device_may_wakeup(ckdev->dev))
pm_wakeup_event(ckdev->dev, 0);
else if (queued_during_suspend)
return NOTIFY_OK;
pm_wakeup_event(ckdev->dev, 0);
val = get_unaligned_le32(&ckdev->ec->event_data.data.sysrq);
dev_dbg(ckdev->dev, "sysrq code from EC: %#x\n", val);
@ -280,10 +262,7 @@ static int cros_ec_keyb_work(struct notifier_block *nb,
case EC_MKBP_EVENT_BUTTON:
case EC_MKBP_EVENT_SWITCH:
if (device_may_wakeup(ckdev->dev))
pm_wakeup_event(ckdev->dev, 0);
else if (queued_during_suspend)
return NOTIFY_OK;
pm_wakeup_event(ckdev->dev, 0);
if (ckdev->ec->event_data.event_type == EC_MKBP_EVENT_BUTTON) {
val = get_unaligned_le32(
@ -683,6 +662,6 @@ static struct platform_driver cros_ec_keyb_driver = {
module_platform_driver(cros_ec_keyb_driver);
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("ChromeOS EC keyboard driver");
MODULE_ALIAS("platform:cros-ec-keyb");

View File

@ -196,7 +196,7 @@ static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata,
ssize_t ret;
int i;
bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL);
bits = bitmap_zalloc(n_events, GFP_KERNEL);
if (!bits)
return -ENOMEM;
@ -216,7 +216,7 @@ static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata,
buf[ret++] = '\n';
buf[ret] = '\0';
kfree(bits);
bitmap_free(bits);
return ret;
}
@ -240,7 +240,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
ssize_t error;
int i;
bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL);
bits = bitmap_zalloc(n_events, GFP_KERNEL);
if (!bits)
return -ENOMEM;
@ -284,7 +284,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
mutex_unlock(&ddata->disable_lock);
out:
kfree(bits);
bitmap_free(bits);
return error;
}

View File

@ -1,11 +1,7 @@
/*
* Driver for the IMX keypad port.
* Copyright (C) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.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.
*/
// SPDX-License-Identifier: GPL-2.0
//
// Driver for the IMX keypad port.
// Copyright (C) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
#include <linux/clk.h>
#include <linux/delay.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <j.cormack@doc.ic.ac.uk>, or by paper mail:
* Justin Cormack, 68 Dartmouth Park Road, London NW5 1SN, UK.
*/
#include <linux/slab.h>

View File

@ -1,14 +1,7 @@
/*
* Driver for the IMX SNVS ON/OFF Power Key
* Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
// SPDX-License-Identifier: GPL-2.0+
//
// Driver for the IMX SNVS ON/OFF Power Key
// Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
#include <linux/device.h>
#include <linux/err.h>

View File

@ -23,10 +23,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <marek.vasut@gmail.com>, or by paper mail:
* Marek Vasut, Liskovecka 559, Frydek-Mistek, 738 01 Czech Republic
*/
#include <linux/slab.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/delay.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/slab.h>

View File

@ -466,7 +466,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
remote->in_endpoint = endpoint;
remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */
remote->in_buffer = usb_alloc_coherent(udev, RECV_SIZE, GFP_ATOMIC, &remote->in_dma);
remote->in_buffer = usb_alloc_coherent(udev, RECV_SIZE, GFP_KERNEL, &remote->in_dma);
if (!remote->in_buffer) {
error = -ENOMEM;
goto fail1;

View File

@ -20,6 +20,7 @@
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/regmap.h>
@ -28,6 +29,7 @@
#define PON_RT_STS 0x10
#define PON_KPDPWR_N_SET BIT(0)
#define PON_RESIN_N_SET BIT(1)
#define PON_PS_HOLD_RST_CTL 0x5a
#define PON_PS_HOLD_RST_CTL2 0x5b
@ -38,10 +40,15 @@
#define PON_PULL_CTL 0x70
#define PON_KPDPWR_PULL_UP BIT(1)
#define PON_RESIN_PULL_UP BIT(0)
#define PON_DBC_CTL 0x71
#define PON_DBC_DELAY_MASK 0x7
struct pm8941_data {
unsigned int pull_up_bit;
unsigned int status_bit;
};
struct pm8941_pwrkey {
struct device *dev;
@ -52,6 +59,9 @@ struct pm8941_pwrkey {
unsigned int revision;
struct notifier_block reboot_notifier;
u32 code;
const struct pm8941_data *data;
};
static int pm8941_reboot_notify(struct notifier_block *nb,
@ -124,7 +134,8 @@ static irqreturn_t pm8941_pwrkey_irq(int irq, void *_data)
if (error)
return IRQ_HANDLED;
input_report_key(pwrkey->input, KEY_POWER, !!(sts & PON_KPDPWR_N_SET));
input_report_key(pwrkey->input, pwrkey->code,
sts & pwrkey->data->status_bit);
input_sync(pwrkey->input);
return IRQ_HANDLED;
@ -157,6 +168,7 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
{
struct pm8941_pwrkey *pwrkey;
bool pull_up;
struct device *parent;
u32 req_delay;
int error;
@ -175,12 +187,30 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
return -ENOMEM;
pwrkey->dev = &pdev->dev;
pwrkey->data = of_device_get_match_data(&pdev->dev);
pwrkey->regmap = dev_get_regmap(pdev->dev.parent, NULL);
parent = pdev->dev.parent;
pwrkey->regmap = dev_get_regmap(parent, NULL);
if (!pwrkey->regmap) {
dev_err(&pdev->dev, "failed to locate regmap\n");
return -ENODEV;
/*
* We failed to get regmap for parent. Let's see if we are
* a child of pon node and read regmap and reg from its
* parent.
*/
pwrkey->regmap = dev_get_regmap(parent->parent, NULL);
if (!pwrkey->regmap) {
dev_err(&pdev->dev, "failed to locate regmap\n");
return -ENODEV;
}
error = of_property_read_u32(parent->of_node,
"reg", &pwrkey->baseaddr);
} else {
error = of_property_read_u32(pdev->dev.of_node, "reg",
&pwrkey->baseaddr);
}
if (error)
return error;
pwrkey->irq = platform_get_irq(pdev, 0);
if (pwrkey->irq < 0) {
@ -188,11 +218,6 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
return pwrkey->irq;
}
error = of_property_read_u32(pdev->dev.of_node, "reg",
&pwrkey->baseaddr);
if (error)
return error;
error = regmap_read(pwrkey->regmap, pwrkey->baseaddr + PON_REV2,
&pwrkey->revision);
if (error) {
@ -200,13 +225,21 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
return error;
}
error = of_property_read_u32(pdev->dev.of_node, "linux,code",
&pwrkey->code);
if (error) {
dev_dbg(&pdev->dev,
"no linux,code assuming power (%d)\n", error);
pwrkey->code = KEY_POWER;
}
pwrkey->input = devm_input_allocate_device(&pdev->dev);
if (!pwrkey->input) {
dev_dbg(&pdev->dev, "unable to allocate input device\n");
return -ENOMEM;
}
input_set_capability(pwrkey->input, EV_KEY, KEY_POWER);
input_set_capability(pwrkey->input, EV_KEY, pwrkey->code);
pwrkey->input->name = "pm8941_pwrkey";
pwrkey->input->phys = "pm8941_pwrkey/input0";
@ -225,8 +258,8 @@ static int pm8941_pwrkey_probe(struct platform_device *pdev)
error = regmap_update_bits(pwrkey->regmap,
pwrkey->baseaddr + PON_PULL_CTL,
PON_KPDPWR_PULL_UP,
pull_up ? PON_KPDPWR_PULL_UP : 0);
pwrkey->data->pull_up_bit,
pull_up ? pwrkey->data->pull_up_bit : 0);
if (error) {
dev_err(&pdev->dev, "failed to set pull: %d\n", error);
return error;
@ -271,8 +304,19 @@ static int pm8941_pwrkey_remove(struct platform_device *pdev)
return 0;
}
static const struct pm8941_data pwrkey_data = {
.pull_up_bit = PON_KPDPWR_PULL_UP,
.status_bit = PON_KPDPWR_N_SET,
};
static const struct pm8941_data resin_data = {
.pull_up_bit = PON_RESIN_PULL_UP,
.status_bit = PON_RESIN_N_SET,
};
static const struct of_device_id pm8941_pwr_key_id_table[] = {
{ .compatible = "qcom,pm8941-pwrkey" },
{ .compatible = "qcom,pm8941-pwrkey", .data = &pwrkey_data },
{ .compatible = "qcom,pm8941-resin", .data = &resin_data },
{ }
};
MODULE_DEVICE_TABLE(of, pm8941_pwr_key_id_table);

View File

@ -277,7 +277,7 @@ static int powermate_input_event(struct input_dev *dev, unsigned int type, unsig
static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_device *pm)
{
pm->data = usb_alloc_coherent(udev, POWERMATE_PAYLOAD_SIZE_MAX,
GFP_ATOMIC, &pm->data_dma);
GFP_KERNEL, &pm->data_dma);
if (!pm->data)
return -1;

View File

@ -63,6 +63,9 @@ static void xenkbd_disconnect_backend(struct xenkbd_info *);
static void xenkbd_handle_motion_event(struct xenkbd_info *info,
struct xenkbd_motion *motion)
{
if (unlikely(!info->ptr))
return;
input_report_rel(info->ptr, REL_X, motion->rel_x);
input_report_rel(info->ptr, REL_Y, motion->rel_y);
if (motion->rel_z)
@ -73,6 +76,9 @@ static void xenkbd_handle_motion_event(struct xenkbd_info *info,
static void xenkbd_handle_position_event(struct xenkbd_info *info,
struct xenkbd_position *pos)
{
if (unlikely(!info->ptr))
return;
input_report_abs(info->ptr, ABS_X, pos->abs_x);
input_report_abs(info->ptr, ABS_Y, pos->abs_y);
if (pos->rel_z)
@ -97,6 +103,9 @@ static void xenkbd_handle_key_event(struct xenkbd_info *info,
return;
}
if (unlikely(!dev))
return;
input_event(dev, EV_KEY, key->keycode, value);
input_sync(dev);
}
@ -192,7 +201,7 @@ static int xenkbd_probe(struct xenbus_device *dev,
const struct xenbus_device_id *id)
{
int ret, i;
unsigned int abs, touch;
bool with_mtouch, with_kbd, with_ptr;
struct xenkbd_info *info;
struct input_dev *kbd, *ptr, *mtouch;
@ -211,106 +220,127 @@ static int xenkbd_probe(struct xenbus_device *dev,
if (!info->page)
goto error_nomem;
/* Set input abs params to match backend screen res */
abs = xenbus_read_unsigned(dev->otherend,
XENKBD_FIELD_FEAT_ABS_POINTER, 0);
ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend,
XENKBD_FIELD_WIDTH,
ptr_size[KPARAM_X]);
ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend,
XENKBD_FIELD_HEIGHT,
ptr_size[KPARAM_Y]);
if (abs) {
ret = xenbus_write(XBT_NIL, dev->nodename,
XENKBD_FIELD_REQ_ABS_POINTER, "1");
if (ret) {
pr_warn("xenkbd: can't request abs-pointer\n");
abs = 0;
}
}
/*
* The below are reverse logic, e.g. if the feature is set, then
* do not expose the corresponding virtual device.
*/
with_kbd = !xenbus_read_unsigned(dev->otherend,
XENKBD_FIELD_FEAT_DSBL_KEYBRD, 0);
touch = xenbus_read_unsigned(dev->nodename,
XENKBD_FIELD_FEAT_MTOUCH, 0);
if (touch) {
with_ptr = !xenbus_read_unsigned(dev->otherend,
XENKBD_FIELD_FEAT_DSBL_POINTER, 0);
/* Direct logic: if set, then create multi-touch device. */
with_mtouch = xenbus_read_unsigned(dev->otherend,
XENKBD_FIELD_FEAT_MTOUCH, 0);
if (with_mtouch) {
ret = xenbus_write(XBT_NIL, dev->nodename,
XENKBD_FIELD_REQ_MTOUCH, "1");
if (ret) {
pr_warn("xenkbd: can't request multi-touch");
touch = 0;
with_mtouch = 0;
}
}
/* keyboard */
kbd = input_allocate_device();
if (!kbd)
goto error_nomem;
kbd->name = "Xen Virtual Keyboard";
kbd->phys = info->phys;
kbd->id.bustype = BUS_PCI;
kbd->id.vendor = 0x5853;
kbd->id.product = 0xffff;
if (with_kbd) {
kbd = input_allocate_device();
if (!kbd)
goto error_nomem;
kbd->name = "Xen Virtual Keyboard";
kbd->phys = info->phys;
kbd->id.bustype = BUS_PCI;
kbd->id.vendor = 0x5853;
kbd->id.product = 0xffff;
__set_bit(EV_KEY, kbd->evbit);
for (i = KEY_ESC; i < KEY_UNKNOWN; i++)
__set_bit(i, kbd->keybit);
for (i = KEY_OK; i < KEY_MAX; i++)
__set_bit(i, kbd->keybit);
__set_bit(EV_KEY, kbd->evbit);
for (i = KEY_ESC; i < KEY_UNKNOWN; i++)
__set_bit(i, kbd->keybit);
for (i = KEY_OK; i < KEY_MAX; i++)
__set_bit(i, kbd->keybit);
ret = input_register_device(kbd);
if (ret) {
input_free_device(kbd);
xenbus_dev_fatal(dev, ret, "input_register_device(kbd)");
goto error;
ret = input_register_device(kbd);
if (ret) {
input_free_device(kbd);
xenbus_dev_fatal(dev, ret,
"input_register_device(kbd)");
goto error;
}
info->kbd = kbd;
}
info->kbd = kbd;
/* pointing device */
ptr = input_allocate_device();
if (!ptr)
goto error_nomem;
ptr->name = "Xen Virtual Pointer";
ptr->phys = info->phys;
ptr->id.bustype = BUS_PCI;
ptr->id.vendor = 0x5853;
ptr->id.product = 0xfffe;
if (with_ptr) {
unsigned int abs;
if (abs) {
__set_bit(EV_ABS, ptr->evbit);
input_set_abs_params(ptr, ABS_X, 0, ptr_size[KPARAM_X], 0, 0);
input_set_abs_params(ptr, ABS_Y, 0, ptr_size[KPARAM_Y], 0, 0);
} else {
input_set_capability(ptr, EV_REL, REL_X);
input_set_capability(ptr, EV_REL, REL_Y);
/* Set input abs params to match backend screen res */
abs = xenbus_read_unsigned(dev->otherend,
XENKBD_FIELD_FEAT_ABS_POINTER, 0);
ptr_size[KPARAM_X] = xenbus_read_unsigned(dev->otherend,
XENKBD_FIELD_WIDTH,
ptr_size[KPARAM_X]);
ptr_size[KPARAM_Y] = xenbus_read_unsigned(dev->otherend,
XENKBD_FIELD_HEIGHT,
ptr_size[KPARAM_Y]);
if (abs) {
ret = xenbus_write(XBT_NIL, dev->nodename,
XENKBD_FIELD_REQ_ABS_POINTER, "1");
if (ret) {
pr_warn("xenkbd: can't request abs-pointer\n");
abs = 0;
}
}
ptr = input_allocate_device();
if (!ptr)
goto error_nomem;
ptr->name = "Xen Virtual Pointer";
ptr->phys = info->phys;
ptr->id.bustype = BUS_PCI;
ptr->id.vendor = 0x5853;
ptr->id.product = 0xfffe;
if (abs) {
__set_bit(EV_ABS, ptr->evbit);
input_set_abs_params(ptr, ABS_X, 0,
ptr_size[KPARAM_X], 0, 0);
input_set_abs_params(ptr, ABS_Y, 0,
ptr_size[KPARAM_Y], 0, 0);
} else {
input_set_capability(ptr, EV_REL, REL_X);
input_set_capability(ptr, EV_REL, REL_Y);
}
input_set_capability(ptr, EV_REL, REL_WHEEL);
__set_bit(EV_KEY, ptr->evbit);
for (i = BTN_LEFT; i <= BTN_TASK; i++)
__set_bit(i, ptr->keybit);
ret = input_register_device(ptr);
if (ret) {
input_free_device(ptr);
xenbus_dev_fatal(dev, ret,
"input_register_device(ptr)");
goto error;
}
info->ptr = ptr;
}
input_set_capability(ptr, EV_REL, REL_WHEEL);
__set_bit(EV_KEY, ptr->evbit);
for (i = BTN_LEFT; i <= BTN_TASK; i++)
__set_bit(i, ptr->keybit);
ret = input_register_device(ptr);
if (ret) {
input_free_device(ptr);
xenbus_dev_fatal(dev, ret, "input_register_device(ptr)");
goto error;
}
info->ptr = ptr;
/* multi-touch device */
if (touch) {
if (with_mtouch) {
int num_cont, width, height;
mtouch = input_allocate_device();
if (!mtouch)
goto error_nomem;
num_cont = xenbus_read_unsigned(info->xbdev->nodename,
num_cont = xenbus_read_unsigned(info->xbdev->otherend,
XENKBD_FIELD_MT_NUM_CONTACTS,
1);
width = xenbus_read_unsigned(info->xbdev->nodename,
width = xenbus_read_unsigned(info->xbdev->otherend,
XENKBD_FIELD_MT_WIDTH,
XENFB_WIDTH);
height = xenbus_read_unsigned(info->xbdev->nodename,
height = xenbus_read_unsigned(info->xbdev->otherend,
XENKBD_FIELD_MT_HEIGHT,
XENFB_HEIGHT);
@ -346,6 +376,11 @@ static int xenkbd_probe(struct xenbus_device *dev,
info->mtouch = mtouch;
}
if (!(with_kbd || with_ptr || with_mtouch)) {
ret = -ENXIO;
goto error;
}
ret = xenkbd_connect_backend(dev, info);
if (ret < 0)
goto error;

View File

@ -894,12 +894,12 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* allocate usb buffers */
yld->irq_data = usb_alloc_coherent(udev, USB_PKT_LEN,
GFP_ATOMIC, &yld->irq_dma);
GFP_KERNEL, &yld->irq_dma);
if (yld->irq_data == NULL)
return usb_cleanup(yld, -ENOMEM);
yld->ctl_data = usb_alloc_coherent(udev, USB_PKT_LEN,
GFP_ATOMIC, &yld->ctl_dma);
GFP_KERNEL, &yld->ctl_dma);
if (!yld->ctl_data)
return usb_cleanup(yld, -ENOMEM);

View File

@ -472,6 +472,7 @@ static int atp_status_check(struct urb *urb)
dev->info->datalen, dev->urb->actual_length);
dev->overflow_warned = true;
}
/* fall through */
case -ECONNRESET:
case -ENOENT:
case -ESHUTDOWN:
@ -810,7 +811,7 @@ static int atp_open(struct input_dev *input)
{
struct atp *dev = input_get_drvdata(input);
if (usb_submit_urb(dev->urb, GFP_ATOMIC))
if (usb_submit_urb(dev->urb, GFP_KERNEL))
return -EIO;
dev->open = true;
@ -976,7 +977,7 @@ static int atp_recover(struct atp *dev)
if (error)
return error;
if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC))
if (dev->open && usb_submit_urb(dev->urb, GFP_KERNEL))
return -EIO;
return 0;
@ -994,7 +995,7 @@ static int atp_resume(struct usb_interface *iface)
{
struct atp *dev = usb_get_intfdata(iface);
if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC))
if (dev->open && usb_submit_urb(dev->urb, GFP_KERNEL))
return -EIO;
return 0;

View File

@ -2554,6 +2554,7 @@ static int cyapa_gen5_do_operational_check(struct cyapa *cyapa)
}
cyapa->state = CYAPA_STATE_GEN5_APP;
/* fall through */
case CYAPA_STATE_GEN5_APP:
/*

View File

@ -680,6 +680,7 @@ static int cyapa_gen6_operational_check(struct cyapa *cyapa)
}
cyapa->state = CYAPA_STATE_GEN6_APP;
/* fall through */
case CYAPA_STATE_GEN6_APP:
/*

View File

@ -387,7 +387,7 @@ static int elan_smbus_prepare_fw_update(struct i2c_client *client)
len = i2c_smbus_read_block_data(client,
ETP_SMBUS_IAP_PASSWORD_READ,
val);
if (len < sizeof(u16)) {
if (len < (int)sizeof(u16)) {
error = len < 0 ? len : -EIO;
dev_err(dev, "failed to read iap password: %d\n",
error);

View File

@ -340,7 +340,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
*/
if (packet[3] & 0x80)
fingers = 4;
/* pass through... */
/* fall through */
case 1:
/*
* byte 1: . . . . x11 x10 x9 x8

View File

@ -26,10 +26,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/module.h>

View File

@ -27,10 +27,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/module.h>

View File

@ -23,10 +23,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/module.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/delay.h>
@ -143,7 +139,8 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data)
switch (sermouse->type) {
case SERIO_MS:
sermouse->type = SERIO_MP;
sermouse->type = SERIO_MP;
/* fall through */
case SERIO_MP:
if ((data >> 2) & 3) break; /* M++ Wireless Extension packet. */
@ -154,6 +151,7 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data)
case SERIO_MZP:
case SERIO_MZPP:
input_report_key(dev, BTN_SIDE, (data >> 5) & 1);
/* fall through */
case SERIO_MZ:
input_report_key(dev, BTN_MIDDLE, (data >> 4) & 1);

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/delay.h>

View File

@ -573,6 +573,9 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
port = &i8042_ports[port_no];
serio = port->exists ? port->serio : NULL;
if (irq && serio)
pm_wakeup_event(&serio->dev, 0);
filter_dbg(port->driver_bound, data, "<- i8042 (interrupt, %d, %d%s%s)\n",
port_no, irq,
dfl & SERIO_PARITY ? ", bad parity" : "",

View File

@ -23,10 +23,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/module.h>

View File

@ -21,10 +21,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/module.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

View File

@ -1712,7 +1712,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
}
aiptek->data = usb_alloc_coherent(usbdev, AIPTEK_PACKET_LENGTH,
GFP_ATOMIC, &aiptek->data_dma);
GFP_KERNEL, &aiptek->data_dma);
if (!aiptek->data) {
dev_warn(&intf->dev, "cannot allocate usb buffer\n");
goto fail1;

View File

@ -164,6 +164,18 @@ config TOUCHSCREEN_BU21013
To compile this driver as a module, choose M here: the
module will be called bu21013_ts.
config TOUCHSCREEN_BU21029
tristate "Rohm BU21029 based touch panel controllers"
depends on I2C
help
Say Y here if you have a Rohm BU21029 touchscreen controller
connected to your system.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called bu21029_ts.
config TOUCHSCREEN_CHIPONE_ICN8318
tristate "chipone icn8318 touchscreen controller"
depends on GPIOLIB || COMPILE_TEST

View File

@ -19,6 +19,7 @@ obj-$(CONFIG_TOUCHSCREEN_AR1021_I2C) += ar1021_i2c.o
obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o
obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o
obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o
obj-$(CONFIG_TOUCHSCREEN_BU21029) += bu21029_ts.o
obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8318) += chipone_icn8318.o
obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8505) += chipone_icn8505.o
obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o

View File

@ -75,6 +75,7 @@
#define MXT_SPT_DIGITIZER_T43 43
#define MXT_SPT_MESSAGECOUNT_T44 44
#define MXT_SPT_CTECONFIG_T46 46
#define MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71 71
#define MXT_TOUCH_MULTITOUCHSCREEN_T100 100
/* MXT_GEN_MESSAGE_T5 object */
@ -88,12 +89,12 @@
#define MXT_COMMAND_DIAGNOSTIC 5
/* Define for T6 status byte */
#define MXT_T6_STATUS_RESET (1 << 7)
#define MXT_T6_STATUS_OFL (1 << 6)
#define MXT_T6_STATUS_SIGERR (1 << 5)
#define MXT_T6_STATUS_CAL (1 << 4)
#define MXT_T6_STATUS_CFGERR (1 << 3)
#define MXT_T6_STATUS_COMSERR (1 << 2)
#define MXT_T6_STATUS_RESET BIT(7)
#define MXT_T6_STATUS_OFL BIT(6)
#define MXT_T6_STATUS_SIGERR BIT(5)
#define MXT_T6_STATUS_CAL BIT(4)
#define MXT_T6_STATUS_CFGERR BIT(3)
#define MXT_T6_STATUS_COMSERR BIT(2)
/* MXT_GEN_POWER_T7 field */
struct t7_config {
@ -112,14 +113,14 @@ struct t7_config {
#define MXT_T9_RANGE 18
/* MXT_TOUCH_MULTI_T9 status */
#define MXT_T9_UNGRIP (1 << 0)
#define MXT_T9_SUPPRESS (1 << 1)
#define MXT_T9_AMP (1 << 2)
#define MXT_T9_VECTOR (1 << 3)
#define MXT_T9_MOVE (1 << 4)
#define MXT_T9_RELEASE (1 << 5)
#define MXT_T9_PRESS (1 << 6)
#define MXT_T9_DETECT (1 << 7)
#define MXT_T9_UNGRIP BIT(0)
#define MXT_T9_SUPPRESS BIT(1)
#define MXT_T9_AMP BIT(2)
#define MXT_T9_VECTOR BIT(3)
#define MXT_T9_MOVE BIT(4)
#define MXT_T9_RELEASE BIT(5)
#define MXT_T9_PRESS BIT(6)
#define MXT_T9_DETECT BIT(7)
struct t9_range {
__le16 x;
@ -127,9 +128,9 @@ struct t9_range {
} __packed;
/* MXT_TOUCH_MULTI_T9 orient */
#define MXT_T9_ORIENT_SWITCH (1 << 0)
#define MXT_T9_ORIENT_INVERTX (1 << 1)
#define MXT_T9_ORIENT_INVERTY (1 << 2)
#define MXT_T9_ORIENT_SWITCH BIT(0)
#define MXT_T9_ORIENT_INVERTX BIT(1)
#define MXT_T9_ORIENT_INVERTY BIT(2)
/* MXT_SPT_COMMSCONFIG_T18 */
#define MXT_COMMS_CTRL 0
@ -214,7 +215,7 @@ enum t100_type {
#define MXT_FRAME_CRC_PASS 0x04
#define MXT_APP_CRC_FAIL 0x40 /* valid 7 8 bit only */
#define MXT_BOOT_STATUS_MASK 0x3f
#define MXT_BOOT_EXTENDED_ID (1 << 5)
#define MXT_BOOT_EXTENDED_ID BIT(5)
#define MXT_BOOT_ID_MASK 0x1f
/* Touchscreen absolute values */
@ -276,6 +277,19 @@ enum mxt_suspend_mode {
MXT_SUSPEND_T9_CTRL = 1,
};
/* Config update context */
struct mxt_cfg {
u8 *raw;
size_t raw_size;
off_t raw_pos;
u8 *mem;
size_t mem_size;
int start_ofs;
struct mxt_info info;
};
/* Each client has this additional data */
struct mxt_data {
struct i2c_client *client;
@ -317,6 +331,7 @@ struct mxt_data {
u8 T6_reportid;
u16 T6_address;
u16 T7_address;
u16 T71_address;
u8 T9_reportid_min;
u8 T9_reportid_max;
u8 T19_reportid;
@ -382,6 +397,7 @@ static bool mxt_object_readable(unsigned int type)
case MXT_SPT_USERDATA_T38:
case MXT_SPT_DIGITIZER_T43:
case MXT_SPT_CTECONFIG_T46:
case MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71:
return true;
default:
return false;
@ -712,13 +728,13 @@ static void mxt_proc_t6_messages(struct mxt_data *data, u8 *msg)
u8 status = msg[1];
u32 crc = msg[2] | (msg[3] << 8) | (msg[4] << 16);
complete(&data->crc_completion);
if (crc != data->config_crc) {
data->config_crc = crc;
dev_dbg(dev, "T6 Config Checksum: 0x%06X\n", crc);
}
complete(&data->crc_completion);
/* Detect reset */
if (status & MXT_T6_STATUS_RESET)
complete(&data->reset_completion);
@ -827,6 +843,10 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message)
mxt_input_sync(data);
}
/* if active, pressure must be non-zero */
if (!amplitude)
amplitude = MXT_PRESSURE_DEFAULT;
/* Touch active */
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1);
input_report_abs(input_dev, ABS_MT_POSITION_X, x);
@ -1279,12 +1299,7 @@ static u32 mxt_calculate_crc(u8 *base, off_t start_off, off_t end_off)
return crc;
}
static int mxt_prepare_cfg_mem(struct mxt_data *data,
const struct firmware *cfg,
unsigned int data_pos,
unsigned int cfg_start_ofs,
u8 *config_mem,
size_t config_mem_size)
static int mxt_prepare_cfg_mem(struct mxt_data *data, struct mxt_cfg *cfg)
{
struct device *dev = &data->client->dev;
struct mxt_object *object;
@ -1295,9 +1310,9 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
u16 reg;
u8 val;
while (data_pos < cfg->size) {
while (cfg->raw_pos < cfg->raw_size) {
/* Read type, instance, length */
ret = sscanf(cfg->data + data_pos, "%x %x %x%n",
ret = sscanf(cfg->raw + cfg->raw_pos, "%x %x %x%n",
&type, &instance, &size, &offset);
if (ret == 0) {
/* EOF */
@ -1306,20 +1321,20 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
dev_err(dev, "Bad format: failed to parse object\n");
return -EINVAL;
}
data_pos += offset;
cfg->raw_pos += offset;
object = mxt_get_object(data, type);
if (!object) {
/* Skip object */
for (i = 0; i < size; i++) {
ret = sscanf(cfg->data + data_pos, "%hhx%n",
ret = sscanf(cfg->raw + cfg->raw_pos, "%hhx%n",
&val, &offset);
if (ret != 1) {
dev_err(dev, "Bad format in T%d at %d\n",
type, i);
return -EINVAL;
}
data_pos += offset;
cfg->raw_pos += offset;
}
continue;
}
@ -1354,7 +1369,7 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
reg = object->start_address + mxt_obj_size(object) * instance;
for (i = 0; i < size; i++) {
ret = sscanf(cfg->data + data_pos, "%hhx%n",
ret = sscanf(cfg->raw + cfg->raw_pos, "%hhx%n",
&val,
&offset);
if (ret != 1) {
@ -1362,15 +1377,15 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
type, i);
return -EINVAL;
}
data_pos += offset;
cfg->raw_pos += offset;
if (i > mxt_obj_size(object))
continue;
byte_offset = reg + i - cfg_start_ofs;
byte_offset = reg + i - cfg->start_ofs;
if (byte_offset >= 0 && byte_offset < config_mem_size) {
*(config_mem + byte_offset) = val;
if (byte_offset >= 0 && byte_offset < cfg->mem_size) {
*(cfg->mem + byte_offset) = val;
} else {
dev_err(dev, "Bad object: reg:%d, T%d, ofs=%d\n",
reg, object->type, byte_offset);
@ -1382,22 +1397,21 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
return 0;
}
static int mxt_upload_cfg_mem(struct mxt_data *data, unsigned int cfg_start,
u8 *config_mem, size_t config_mem_size)
static int mxt_upload_cfg_mem(struct mxt_data *data, struct mxt_cfg *cfg)
{
unsigned int byte_offset = 0;
int error;
/* Write configuration as blocks */
while (byte_offset < config_mem_size) {
unsigned int size = config_mem_size - byte_offset;
while (byte_offset < cfg->mem_size) {
unsigned int size = cfg->mem_size - byte_offset;
if (size > MXT_MAX_BLOCK_WRITE)
size = MXT_MAX_BLOCK_WRITE;
error = __mxt_write_reg(data->client,
cfg_start + byte_offset,
size, config_mem + byte_offset);
cfg->start_ofs + byte_offset,
size, cfg->mem + byte_offset);
if (error) {
dev_err(&data->client->dev,
"Config write error, ret=%d\n", error);
@ -1431,65 +1445,75 @@ static int mxt_init_t7_power_cfg(struct mxt_data *data);
* <SIZE> - 2-byte object size as hex
* <CONTENTS> - array of <SIZE> 1-byte hex values
*/
static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
{
struct device *dev = &data->client->dev;
struct mxt_info cfg_info;
struct mxt_cfg cfg;
int ret;
int offset;
int data_pos;
int i;
int cfg_start_ofs;
u32 info_crc, config_crc, calculated_crc;
u8 *config_mem;
size_t config_mem_size;
u16 crc_start = 0;
/* Make zero terminated copy of the OBP_RAW file */
cfg.raw = kmemdup_nul(fw->data, fw->size, GFP_KERNEL);
if (!cfg.raw)
return -ENOMEM;
cfg.raw_size = fw->size;
mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1);
if (strncmp(cfg->data, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) {
if (strncmp(cfg.raw, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) {
dev_err(dev, "Unrecognised config file\n");
return -EINVAL;
ret = -EINVAL;
goto release_raw;
}
data_pos = strlen(MXT_CFG_MAGIC);
cfg.raw_pos = strlen(MXT_CFG_MAGIC);
/* Load information block and check */
for (i = 0; i < sizeof(struct mxt_info); i++) {
ret = sscanf(cfg->data + data_pos, "%hhx%n",
(unsigned char *)&cfg_info + i,
ret = sscanf(cfg.raw + cfg.raw_pos, "%hhx%n",
(unsigned char *)&cfg.info + i,
&offset);
if (ret != 1) {
dev_err(dev, "Bad format\n");
return -EINVAL;
ret = -EINVAL;
goto release_raw;
}
data_pos += offset;
cfg.raw_pos += offset;
}
if (cfg_info.family_id != data->info->family_id) {
if (cfg.info.family_id != data->info->family_id) {
dev_err(dev, "Family ID mismatch!\n");
return -EINVAL;
ret = -EINVAL;
goto release_raw;
}
if (cfg_info.variant_id != data->info->variant_id) {
if (cfg.info.variant_id != data->info->variant_id) {
dev_err(dev, "Variant ID mismatch!\n");
return -EINVAL;
ret = -EINVAL;
goto release_raw;
}
/* Read CRCs */
ret = sscanf(cfg->data + data_pos, "%x%n", &info_crc, &offset);
ret = sscanf(cfg.raw + cfg.raw_pos, "%x%n", &info_crc, &offset);
if (ret != 1) {
dev_err(dev, "Bad format: failed to parse Info CRC\n");
return -EINVAL;
ret = -EINVAL;
goto release_raw;
}
data_pos += offset;
cfg.raw_pos += offset;
ret = sscanf(cfg->data + data_pos, "%x%n", &config_crc, &offset);
ret = sscanf(cfg.raw + cfg.raw_pos, "%x%n", &config_crc, &offset);
if (ret != 1) {
dev_err(dev, "Bad format: failed to parse Config CRC\n");
return -EINVAL;
ret = -EINVAL;
goto release_raw;
}
data_pos += offset;
cfg.raw_pos += offset;
/*
* The Info Block CRC is calculated over mxt_info and the object
@ -1515,39 +1539,39 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
}
/* Malloc memory to store configuration */
cfg_start_ofs = MXT_OBJECT_START +
cfg.start_ofs = MXT_OBJECT_START +
data->info->object_num * sizeof(struct mxt_object) +
MXT_INFO_CHECKSUM_SIZE;
config_mem_size = data->mem_size - cfg_start_ofs;
config_mem = kzalloc(config_mem_size, GFP_KERNEL);
if (!config_mem) {
dev_err(dev, "Failed to allocate memory\n");
return -ENOMEM;
cfg.mem_size = data->mem_size - cfg.start_ofs;
cfg.mem = kzalloc(cfg.mem_size, GFP_KERNEL);
if (!cfg.mem) {
ret = -ENOMEM;
goto release_raw;
}
ret = mxt_prepare_cfg_mem(data, cfg, data_pos, cfg_start_ofs,
config_mem, config_mem_size);
ret = mxt_prepare_cfg_mem(data, &cfg);
if (ret)
goto release_mem;
/* Calculate crc of the received configs (not the raw config file) */
if (data->T7_address < cfg_start_ofs) {
dev_err(dev, "Bad T7 address, T7addr = %x, config offset %x\n",
data->T7_address, cfg_start_ofs);
ret = 0;
goto release_mem;
if (data->T71_address)
crc_start = data->T71_address;
else if (data->T7_address)
crc_start = data->T7_address;
else
dev_warn(dev, "Could not find CRC start\n");
if (crc_start > cfg.start_ofs) {
calculated_crc = mxt_calculate_crc(cfg.mem,
crc_start - cfg.start_ofs,
cfg.mem_size);
if (config_crc > 0 && config_crc != calculated_crc)
dev_warn(dev, "Config CRC in file inconsistent, calculated=%06X, file=%06X\n",
calculated_crc, config_crc);
}
calculated_crc = mxt_calculate_crc(config_mem,
data->T7_address - cfg_start_ofs,
config_mem_size);
if (config_crc > 0 && config_crc != calculated_crc)
dev_warn(dev, "Config CRC error, calculated=%06X, file=%06X\n",
calculated_crc, config_crc);
ret = mxt_upload_cfg_mem(data, cfg_start_ofs,
config_mem, config_mem_size);
ret = mxt_upload_cfg_mem(data, &cfg);
if (ret)
goto release_mem;
@ -1562,8 +1586,10 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg)
/* T7 config may have changed */
mxt_init_t7_power_cfg(data);
release_raw:
kfree(cfg.raw);
release_mem:
kfree(config_mem);
kfree(cfg.mem);
return ret;
}
@ -1591,6 +1617,7 @@ static void mxt_free_object_table(struct mxt_data *data)
data->T5_msg_size = 0;
data->T6_reportid = 0;
data->T7_address = 0;
data->T71_address = 0;
data->T9_reportid_min = 0;
data->T9_reportid_max = 0;
data->T19_reportid = 0;
@ -1656,12 +1683,16 @@ static int mxt_parse_object_table(struct mxt_data *data,
case MXT_GEN_POWER_T7:
data->T7_address = object->start_address;
break;
case MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71:
data->T71_address = object->start_address;
break;
case MXT_TOUCH_MULTI_T9:
data->multitouch = MXT_TOUCH_MULTI_T9;
/* Only handle messages from first T9 instance */
data->T9_reportid_min = min_id;
data->T9_reportid_max = max_id;
data->num_touchids = object->num_report_ids
* mxt_obj_instances(object);
data->T9_reportid_max = min_id +
object->num_report_ids - 1;
data->num_touchids = object->num_report_ids;
break;
case MXT_SPT_MESSAGECOUNT_T44:
data->T44_address = object->start_address;
@ -1981,10 +2012,8 @@ static int mxt_initialize_input_device(struct mxt_data *data)
/* Register input device */
input_dev = input_allocate_device();
if (!input_dev) {
dev_err(dev, "Failed to allocate memory\n");
if (!input_dev)
return -ENOMEM;
}
input_dev->name = "Atmel maXTouch Touchscreen";
input_dev->phys = data->phys;
@ -2054,12 +2083,6 @@ static int mxt_initialize_input_device(struct mxt_data *data)
0, 255, 0, 0);
}
if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 &&
data->t100_aux_ampl) {
input_set_abs_params(input_dev, ABS_MT_PRESSURE,
0, 255, 0, 0);
}
if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 &&
data->t100_aux_vect) {
input_set_abs_params(input_dev, ABS_MT_ORIENTATION,

View File

@ -0,0 +1,484 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Rohm BU21029 touchscreen controller driver
*
* Copyright (C) 2015-2018 Bosch Sicherheitssysteme GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/touchscreen.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
#include <linux/timer.h>
/*
* HW_ID1 Register (PAGE=0, ADDR=0x0E, Reset value=0x02, Read only)
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | HW_IDH |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* HW_ID2 Register (PAGE=0, ADDR=0x0F, Reset value=0x29, Read only)
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | HW_IDL |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* HW_IDH: high 8bits of IC's ID
* HW_IDL: low 8bits of IC's ID
*/
#define BU21029_HWID_REG (0x0E << 3)
#define SUPPORTED_HWID 0x0229
/*
* CFR0 Register (PAGE=0, ADDR=0x00, Reset value=0x20)
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | 0 | 0 | CALIB | INTRM | 0 | 0 | 0 | 0 |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* CALIB: 0 = not to use calibration result (*)
* 1 = use calibration result
* INTRM: 0 = INT output depend on "pen down" (*)
* 1 = INT output always "0"
*/
#define BU21029_CFR0_REG (0x00 << 3)
#define CFR0_VALUE 0x00
/*
* CFR1 Register (PAGE=0, ADDR=0x01, Reset value=0xA6)
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | MAV | AVE[2:0] | 0 | SMPL[2:0] |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* MAV: 0 = median average filter off
* 1 = median average filter on (*)
* AVE: AVE+1 = number of average samples for MAV,
* if AVE>SMPL, then AVE=SMPL (=3)
* SMPL: SMPL+1 = number of conversion samples for MAV (=7)
*/
#define BU21029_CFR1_REG (0x01 << 3)
#define CFR1_VALUE 0xA6
/*
* CFR2 Register (PAGE=0, ADDR=0x02, Reset value=0x04)
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | INTVL_TIME[3:0] | TIME_ST_ADC[3:0] |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* INTVL_TIME: waiting time between completion of conversion
* and start of next conversion, only usable in
* autoscan mode (=20.480ms)
* TIME_ST_ADC: waiting time between application of voltage
* to panel and start of A/D conversion (=100us)
*/
#define BU21029_CFR2_REG (0x02 << 3)
#define CFR2_VALUE 0xC9
/*
* CFR3 Register (PAGE=0, ADDR=0x0B, Reset value=0x72)
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | RM8 | STRETCH| PU90K | DUAL | PIDAC_OFS[3:0] |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* RM8: 0 = coordinate resolution is 12bit (*)
* 1 = coordinate resolution is 8bit
* STRETCH: 0 = SCL_STRETCH function off
* 1 = SCL_STRETCH function on (*)
* PU90K: 0 = internal pull-up resistance for touch detection is ~50kohms (*)
* 1 = internal pull-up resistance for touch detection is ~90kohms
* DUAL: 0 = dual touch detection off (*)
* 1 = dual touch detection on
* PIDAC_OFS: dual touch detection circuit adjustment, it is not necessary
* to change this from initial value
*/
#define BU21029_CFR3_REG (0x0B << 3)
#define CFR3_VALUE 0x42
/*
* LDO Register (PAGE=0, ADDR=0x0C, Reset value=0x00)
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | 0 | PVDD[2:0] | 0 | AVDD[2:0] |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* PVDD: output voltage of panel output regulator (=2.000V)
* AVDD: output voltage of analog circuit regulator (=2.000V)
*/
#define BU21029_LDO_REG (0x0C << 3)
#define LDO_VALUE 0x77
/*
* Serial Interface Command Byte 1 (CID=1)
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* | 1 | CF | CMSK | PDM | STP |
* +--------+--------+--------+--------+--------+--------+--------+--------+
* CF: conversion function, see table 3 in datasheet p6 (=0000, automatic scan)
* CMSK: 0 = executes convert function (*)
* 1 = reads the convert result
* PDM: 0 = power down after convert function stops (*)
* 1 = keep power on after convert function stops
* STP: 1 = abort current conversion and power down, set to "0" automatically
*/
#define BU21029_AUTOSCAN 0x80
/*
* The timeout value needs to be larger than INTVL_TIME + tConv4 (sample and
* conversion time), where tConv4 is calculated by formula:
* tPON + tDLY1 + (tTIME_ST_ADC + (tADC * tSMPL) * 2 + tDLY2) * 3
* see figure 8 in datasheet p15 for details of each field.
*/
#define PEN_UP_TIMEOUT_MS 50
#define STOP_DELAY_MIN_US 50
#define STOP_DELAY_MAX_US 1000
#define START_DELAY_MS 2
#define BUF_LEN 8
#define SCALE_12BIT (1 << 12)
#define MAX_12BIT ((1 << 12) - 1)
#define DRIVER_NAME "bu21029"
struct bu21029_ts_data {
struct i2c_client *client;
struct input_dev *in_dev;
struct timer_list timer;
struct regulator *vdd;
struct gpio_desc *reset_gpios;
u32 x_plate_ohms;
struct touchscreen_properties prop;
};
static void bu21029_touch_report(struct bu21029_ts_data *bu21029, const u8 *buf)
{
u16 x, y, z1, z2;
u32 rz;
s32 max_pressure = input_abs_get_max(bu21029->in_dev, ABS_PRESSURE);
/*
* compose upper 8 and lower 4 bits into a 12bit value:
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
* | ByteH | ByteL |
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
* |b07|b06|b05|b04|b03|b02|b01|b00|b07|b06|b05|b04|b03|b02|b01|b00|
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
* |v11|v10|v09|v08|v07|v06|v05|v04|v03|v02|v01|v00| 0 | 0 | 0 | 0 |
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
*/
x = (buf[0] << 4) | (buf[1] >> 4);
y = (buf[2] << 4) | (buf[3] >> 4);
z1 = (buf[4] << 4) | (buf[5] >> 4);
z2 = (buf[6] << 4) | (buf[7] >> 4);
if (z1 && z2) {
/*
* calculate Rz (pressure resistance value) by equation:
* Rz = Rx * (x/Q) * ((z2/z1) - 1), where
* Rx is x-plate resistance,
* Q is the touch screen resolution (8bit = 256, 12bit = 4096)
* x, z1, z2 are the measured positions.
*/
rz = z2 - z1;
rz *= x;
rz *= bu21029->x_plate_ohms;
rz /= z1;
rz = DIV_ROUND_CLOSEST(rz, SCALE_12BIT);
if (rz <= max_pressure) {
touchscreen_report_pos(bu21029->in_dev, &bu21029->prop,
x, y, false);
input_report_abs(bu21029->in_dev, ABS_PRESSURE,
max_pressure - rz);
input_report_key(bu21029->in_dev, BTN_TOUCH, 1);
input_sync(bu21029->in_dev);
}
}
}
static void bu21029_touch_release(struct timer_list *t)
{
struct bu21029_ts_data *bu21029 = from_timer(bu21029, t, timer);
input_report_abs(bu21029->in_dev, ABS_PRESSURE, 0);
input_report_key(bu21029->in_dev, BTN_TOUCH, 0);
input_sync(bu21029->in_dev);
}
static irqreturn_t bu21029_touch_soft_irq(int irq, void *data)
{
struct bu21029_ts_data *bu21029 = data;
u8 buf[BUF_LEN];
int error;
/*
* Read touch data and deassert interrupt (will assert again after
* INTVL_TIME + tConv4 for continuous touch)
*/
error = i2c_smbus_read_i2c_block_data(bu21029->client, BU21029_AUTOSCAN,
sizeof(buf), buf);
if (error < 0)
goto out;
bu21029_touch_report(bu21029, buf);
/* reset timer for pen up detection */
mod_timer(&bu21029->timer,
jiffies + msecs_to_jiffies(PEN_UP_TIMEOUT_MS));
out:
return IRQ_HANDLED;
}
static void bu21029_put_chip_in_reset(struct bu21029_ts_data *bu21029)
{
if (bu21029->reset_gpios) {
gpiod_set_value_cansleep(bu21029->reset_gpios, 1);
usleep_range(STOP_DELAY_MIN_US, STOP_DELAY_MAX_US);
}
}
static int bu21029_start_chip(struct input_dev *dev)
{
struct bu21029_ts_data *bu21029 = input_get_drvdata(dev);
struct i2c_client *i2c = bu21029->client;
struct {
u8 reg;
u8 value;
} init_table[] = {
{BU21029_CFR0_REG, CFR0_VALUE},
{BU21029_CFR1_REG, CFR1_VALUE},
{BU21029_CFR2_REG, CFR2_VALUE},
{BU21029_CFR3_REG, CFR3_VALUE},
{BU21029_LDO_REG, LDO_VALUE}
};
int error, i;
__be16 hwid;
error = regulator_enable(bu21029->vdd);
if (error) {
dev_err(&i2c->dev, "failed to power up chip: %d", error);
return error;
}
/* take chip out of reset */
if (bu21029->reset_gpios) {
gpiod_set_value_cansleep(bu21029->reset_gpios, 0);
msleep(START_DELAY_MS);
}
error = i2c_smbus_read_i2c_block_data(i2c, BU21029_HWID_REG,
sizeof(hwid), (u8 *)&hwid);
if (error < 0) {
dev_err(&i2c->dev, "failed to read HW ID\n");
goto err_out;
}
if (be16_to_cpu(hwid) != SUPPORTED_HWID) {
dev_err(&i2c->dev,
"unsupported HW ID 0x%x\n", be16_to_cpu(hwid));
error = -ENODEV;
goto err_out;
}
for (i = 0; i < ARRAY_SIZE(init_table); ++i) {
error = i2c_smbus_write_byte_data(i2c,
init_table[i].reg,
init_table[i].value);
if (error < 0) {
dev_err(&i2c->dev,
"failed to write %#02x to register %#02x: %d\n",
init_table[i].value, init_table[i].reg,
error);
goto err_out;
}
}
error = i2c_smbus_write_byte(i2c, BU21029_AUTOSCAN);
if (error < 0) {
dev_err(&i2c->dev, "failed to start autoscan\n");
goto err_out;
}
enable_irq(bu21029->client->irq);
return 0;
err_out:
bu21029_put_chip_in_reset(bu21029);
regulator_disable(bu21029->vdd);
return error;
}
static void bu21029_stop_chip(struct input_dev *dev)
{
struct bu21029_ts_data *bu21029 = input_get_drvdata(dev);
disable_irq(bu21029->client->irq);
del_timer_sync(&bu21029->timer);
bu21029_put_chip_in_reset(bu21029);
regulator_disable(bu21029->vdd);
}
static int bu21029_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct bu21029_ts_data *bu21029;
struct input_dev *in_dev;
int error;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_WRITE_BYTE |
I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
dev_err(&client->dev,
"i2c functionality support is not sufficient\n");
return -EIO;
}
bu21029 = devm_kzalloc(&client->dev, sizeof(*bu21029), GFP_KERNEL);
if (!bu21029)
return -ENOMEM;
error = device_property_read_u32(&client->dev, "rohm,x-plate-ohms",
&bu21029->x_plate_ohms);
if (error) {
dev_err(&client->dev,
"invalid 'x-plate-ohms' supplied: %d\n", error);
return error;
}
bu21029->vdd = devm_regulator_get(&client->dev, "vdd");
if (IS_ERR(bu21029->vdd)) {
error = PTR_ERR(bu21029->vdd);
if (error != -EPROBE_DEFER)
dev_err(&client->dev,
"failed to acquire 'vdd' supply: %d\n", error);
return error;
}
bu21029->reset_gpios = devm_gpiod_get_optional(&client->dev,
"reset", GPIOD_OUT_HIGH);
if (IS_ERR(bu21029->reset_gpios)) {
error = PTR_ERR(bu21029->reset_gpios);
if (error != -EPROBE_DEFER)
dev_err(&client->dev,
"failed to acquire 'reset' gpio: %d\n", error);
return error;
}
in_dev = devm_input_allocate_device(&client->dev);
if (!in_dev) {
dev_err(&client->dev, "unable to allocate input device\n");
return -ENOMEM;
}
bu21029->client = client;
bu21029->in_dev = in_dev;
timer_setup(&bu21029->timer, bu21029_touch_release, 0);
in_dev->name = DRIVER_NAME;
in_dev->id.bustype = BUS_I2C;
in_dev->open = bu21029_start_chip;
in_dev->close = bu21029_stop_chip;
input_set_capability(in_dev, EV_KEY, BTN_TOUCH);
input_set_abs_params(in_dev, ABS_X, 0, MAX_12BIT, 0, 0);
input_set_abs_params(in_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
input_set_abs_params(in_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
touchscreen_parse_properties(in_dev, false, &bu21029->prop);
input_set_drvdata(in_dev, bu21029);
irq_set_status_flags(client->irq, IRQ_NOAUTOEN);
error = devm_request_threaded_irq(&client->dev, client->irq,
NULL, bu21029_touch_soft_irq,
IRQF_ONESHOT, DRIVER_NAME, bu21029);
if (error) {
dev_err(&client->dev,
"unable to request touch irq: %d\n", error);
return error;
}
error = input_register_device(in_dev);
if (error) {
dev_err(&client->dev,
"unable to register input device: %d\n", error);
return error;
}
i2c_set_clientdata(client, bu21029);
return 0;
}
static int __maybe_unused bu21029_suspend(struct device *dev)
{
struct i2c_client *i2c = to_i2c_client(dev);
struct bu21029_ts_data *bu21029 = i2c_get_clientdata(i2c);
if (!device_may_wakeup(dev)) {
mutex_lock(&bu21029->in_dev->mutex);
if (bu21029->in_dev->users)
bu21029_stop_chip(bu21029->in_dev);
mutex_unlock(&bu21029->in_dev->mutex);
}
return 0;
}
static int __maybe_unused bu21029_resume(struct device *dev)
{
struct i2c_client *i2c = to_i2c_client(dev);
struct bu21029_ts_data *bu21029 = i2c_get_clientdata(i2c);
if (!device_may_wakeup(dev)) {
mutex_lock(&bu21029->in_dev->mutex);
if (bu21029->in_dev->users)
bu21029_start_chip(bu21029->in_dev);
mutex_unlock(&bu21029->in_dev->mutex);
}
return 0;
}
static SIMPLE_DEV_PM_OPS(bu21029_pm_ops, bu21029_suspend, bu21029_resume);
static const struct i2c_device_id bu21029_ids[] = {
{ DRIVER_NAME, 0 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, bu21029_ids);
#ifdef CONFIG_OF
static const struct of_device_id bu21029_of_ids[] = {
{ .compatible = "rohm,bu21029" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, bu21029_of_ids);
#endif
static struct i2c_driver bu21029_driver = {
.driver = {
.name = DRIVER_NAME,
.of_match_table = of_match_ptr(bu21029_of_ids),
.pm = &bu21029_pm_ops,
},
.id_table = bu21029_ids,
.probe = bu21029_probe,
};
module_i2c_driver(bu21029_driver);
MODULE_AUTHOR("Zhu Yi <yi.zhu5@cn.bosch.com>");
MODULE_DESCRIPTION("Rohm BU21029 touchscreen controller driver");
MODULE_LICENSE("GPL v2");

View File

@ -1,9 +1,9 @@
/*
* Touch Screen driver for EETI's I2C connected touch screen panels
* Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
* Copyright (c) 2009,2018 Daniel Mack <daniel@zonque.org>
*
* See EETI's software guide for the protocol specification:
* http://home.eeti.com.tw/web20/eg/guide.htm
* http://home.eeti.com.tw/documentation.html
*
* Based on migor_ts.c
* Copyright (c) 2008 Magnus Damm
@ -25,28 +25,22 @@
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/input.h>
#include <linux/input/touchscreen.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/timer.h>
#include <linux/gpio/consumer.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
static bool flip_x;
module_param(flip_x, bool, 0644);
MODULE_PARM_DESC(flip_x, "flip x coordinate");
static bool flip_y;
module_param(flip_y, bool, 0644);
MODULE_PARM_DESC(flip_y, "flip y coordinate");
struct eeti_ts {
struct i2c_client *client;
struct input_dev *input;
struct gpio_desc *attn_gpio;
struct touchscreen_properties props;
bool running;
};
@ -73,17 +67,10 @@ static void eeti_ts_report_event(struct eeti_ts *eeti, u8 *buf)
x >>= res - EETI_TS_BITDEPTH;
y >>= res - EETI_TS_BITDEPTH;
if (flip_x)
x = EETI_MAXVAL - x;
if (flip_y)
y = EETI_MAXVAL - y;
if (buf[0] & REPORT_BIT_HAS_PRESSURE)
input_report_abs(eeti->input, ABS_PRESSURE, buf[5]);
input_report_abs(eeti->input, ABS_X, x);
input_report_abs(eeti->input, ABS_Y, y);
touchscreen_report_pos(eeti->input, &eeti->props, x, y, false);
input_report_key(eeti->input, BTN_TOUCH, buf[0] & REPORT_BIT_PRESSED);
input_sync(eeti->input);
}
@ -178,6 +165,8 @@ static int eeti_ts_probe(struct i2c_client *client,
input_set_abs_params(input, ABS_Y, 0, EETI_MAXVAL, 0, 0);
input_set_abs_params(input, ABS_PRESSURE, 0, 0xff, 0, 0);
touchscreen_parse_properties(input, false, &eeti->props);
input->name = client->name;
input->id.bustype = BUS_I2C;
input->open = eeti_ts_open;
@ -262,10 +251,18 @@ static const struct i2c_device_id eeti_ts_id[] = {
};
MODULE_DEVICE_TABLE(i2c, eeti_ts_id);
#ifdef CONFIG_OF
static const struct of_device_id of_eeti_ts_match[] = {
{ .compatible = "eeti,exc3000-i2c", },
{ }
};
#endif
static struct i2c_driver eeti_ts_driver = {
.driver = {
.name = "eeti_ts",
.pm = &eeti_ts_pm,
.of_match_table = of_match_ptr(of_eeti_ts_match),
},
.probe = eeti_ts_probe,
.id_table = eeti_ts_id,
@ -274,5 +271,5 @@ static struct i2c_driver eeti_ts_driver = {
module_i2c_driver(eeti_ts_driver);
MODULE_DESCRIPTION("EETI Touchscreen driver");
MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
MODULE_AUTHOR("Daniel Mack <daniel@zonque.org>");
MODULE_LICENSE("GPL");

View File

@ -1,13 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Driver for EETI eGalax Multiple Touch Controller
*
* Copyright (C) 2011 Freescale Semiconductor, Inc.
*
* based on max11801_ts.c
*
* 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.
*/
/* EETI eGalax serial touch screen controller is a I2C based multiple

View File

@ -352,6 +352,7 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv)
case 1: /* 6-byte protocol */
input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0);
/* fall through */
case 2: /* 4-byte protocol */
input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);

View File

@ -1,16 +1,11 @@
/*
* Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
*
* 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.
*
* Based on driver from 2011:
* Juergen Beisert, Pengutronix <kernel@pengutronix.de>
*
* This is the driver for the imx25 TCQ (Touchscreen Conversion Queue)
* connected to the imx25 ADC.
*/
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (C) 2014-2015 Pengutronix, Markus Pargmann <mpa@pengutronix.de>
// Based on driver from 2011:
// Juergen Beisert, Pengutronix <kernel@pengutronix.de>
//
// This is the driver for the imx25 TCQ (Touchscreen Conversion Queue)
// connected to the imx25 ADC.
#include <linux/clk.h>
#include <linux/device.h>

View File

@ -20,10 +20,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/errno.h>

View File

@ -1,12 +1,8 @@
/*
* Freescale i.MX6UL touchscreen controller driver
*
* Copyright (C) 2015 Freescale Semiconductor, Inc.
*
* 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.
*/
// SPDX-License-Identifier: GPL-2.0
//
// Freescale i.MX6UL touchscreen controller driver
//
// Copyright (C) 2015 Freescale Semiconductor, Inc.
#include <linux/errno.h>
#include <linux/kernel.h>

View File

@ -466,7 +466,7 @@ static bool raydium_i2c_boot_trigger(struct i2c_client *client)
}
}
return 0;
return false;
}
static bool raydium_i2c_fw_trigger(struct i2c_client *client)
@ -492,7 +492,7 @@ static bool raydium_i2c_fw_trigger(struct i2c_client *client)
}
}
return 0;
return false;
}
static int raydium_i2c_check_path(struct i2c_client *client)

View File

@ -1142,7 +1142,7 @@ static int __maybe_unused wdt87xx_resume(struct device *dev)
* The chip may have been reset while system is resuming,
* give it some time to settle.
*/
mdelay(100);
msleep(100);
error = wdt87xx_send_command(client, VND_CMD_START, 0);
if (error)

View File

@ -3859,7 +3859,7 @@ static int __load_dirty_region_bitmap(struct raid_set *rs)
/* Try loading the bitmap unless "raid0", which does not have one */
if (!rs_is_raid0(rs) &&
!test_and_set_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags)) {
r = bitmap_load(&rs->md);
r = md_bitmap_load(&rs->md);
if (r)
DMERR("Failed to load bitmap");
}
@ -3987,8 +3987,8 @@ static int raid_preresume(struct dm_target *ti)
/* Resize bitmap to adjust to changed region size (aka MD bitmap chunksize) */
if (test_bit(RT_FLAG_RS_BITMAP_LOADED, &rs->runtime_flags) && mddev->bitmap &&
mddev->bitmap_info.chunksize != to_bytes(rs->requested_bitmap_chunk_sectors)) {
r = bitmap_resize(mddev->bitmap, mddev->dev_sectors,
to_bytes(rs->requested_bitmap_chunk_sectors), 0);
r = md_bitmap_resize(mddev->bitmap, mddev->dev_sectors,
to_bytes(rs->requested_bitmap_chunk_sectors), 0);
if (r)
DMERR("Failed to resize bitmap");
}

View File

@ -46,8 +46,8 @@ static inline char *bmname(struct bitmap *bitmap)
* if we find our page, we increment the page's refcount so that it stays
* allocated while we're using it
*/
static int bitmap_checkpage(struct bitmap_counts *bitmap,
unsigned long page, int create, int no_hijack)
static int md_bitmap_checkpage(struct bitmap_counts *bitmap,
unsigned long page, int create, int no_hijack)
__releases(bitmap->lock)
__acquires(bitmap->lock)
{
@ -115,7 +115,7 @@ __acquires(bitmap->lock)
/* if page is completely empty, put it back on the free list, or dealloc it */
/* if page was hijacked, unmark the flag so it might get alloced next time */
/* Note: lock should be held when calling this */
static void bitmap_checkfree(struct bitmap_counts *bitmap, unsigned long page)
static void md_bitmap_checkfree(struct bitmap_counts *bitmap, unsigned long page)
{
char *ptr;
@ -280,7 +280,7 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
return -EINVAL;
}
static void bitmap_file_kick(struct bitmap *bitmap);
static void md_bitmap_file_kick(struct bitmap *bitmap);
/*
* write out a page to a file
*/
@ -310,7 +310,7 @@ static void write_page(struct bitmap *bitmap, struct page *page, int wait)
atomic_read(&bitmap->pending_writes)==0);
}
if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags))
bitmap_file_kick(bitmap);
md_bitmap_file_kick(bitmap);
}
static void end_bitmap_write(struct buffer_head *bh, int uptodate)
@ -421,11 +421,11 @@ static int read_page(struct file *file, unsigned long index,
*/
/*
* bitmap_wait_writes() should be called before writing any bitmap
* md_bitmap_wait_writes() should be called before writing any bitmap
* blocks, to ensure previous writes, particularly from
* bitmap_daemon_work(), have completed.
* md_bitmap_daemon_work(), have completed.
*/
static void bitmap_wait_writes(struct bitmap *bitmap)
static void md_bitmap_wait_writes(struct bitmap *bitmap)
{
if (bitmap->storage.file)
wait_event(bitmap->write_wait,
@ -443,7 +443,7 @@ static void bitmap_wait_writes(struct bitmap *bitmap)
/* update the event counter and sync the superblock to disk */
void bitmap_update_sb(struct bitmap *bitmap)
void md_bitmap_update_sb(struct bitmap *bitmap)
{
bitmap_super_t *sb;
@ -476,10 +476,10 @@ void bitmap_update_sb(struct bitmap *bitmap)
kunmap_atomic(sb);
write_page(bitmap, bitmap->storage.sb_page, 1);
}
EXPORT_SYMBOL(bitmap_update_sb);
EXPORT_SYMBOL(md_bitmap_update_sb);
/* print out the bitmap file superblock */
void bitmap_print_sb(struct bitmap *bitmap)
void md_bitmap_print_sb(struct bitmap *bitmap)
{
bitmap_super_t *sb;
@ -518,7 +518,7 @@ void bitmap_print_sb(struct bitmap *bitmap)
*
* Returns: 0 on success, -Exxx on error
*/
static int bitmap_new_disk_sb(struct bitmap *bitmap)
static int md_bitmap_new_disk_sb(struct bitmap *bitmap)
{
bitmap_super_t *sb;
unsigned long chunksize, daemon_sleep, write_behind;
@ -577,7 +577,7 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap)
}
/* read the superblock from the bitmap file and initialize some bitmap fields */
static int bitmap_read_sb(struct bitmap *bitmap)
static int md_bitmap_read_sb(struct bitmap *bitmap)
{
char *reason = NULL;
bitmap_super_t *sb;
@ -727,7 +727,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
bitmap->mddev->bitmap_info.space > sectors_reserved)
bitmap->mddev->bitmap_info.space = sectors_reserved;
if (err) {
bitmap_print_sb(bitmap);
md_bitmap_print_sb(bitmap);
if (bitmap->cluster_slot < 0)
md_cluster_stop(bitmap->mddev);
}
@ -774,9 +774,9 @@ static inline struct page *filemap_get_page(struct bitmap_storage *store,
return store->filemap[file_page_index(store, chunk)];
}
static int bitmap_storage_alloc(struct bitmap_storage *store,
unsigned long chunks, int with_super,
int slot_number)
static int md_bitmap_storage_alloc(struct bitmap_storage *store,
unsigned long chunks, int with_super,
int slot_number)
{
int pnum, offset = 0;
unsigned long num_pages;
@ -830,7 +830,7 @@ static int bitmap_storage_alloc(struct bitmap_storage *store,
return 0;
}
static void bitmap_file_unmap(struct bitmap_storage *store)
static void md_bitmap_file_unmap(struct bitmap_storage *store)
{
struct page **map, *sb_page;
int pages;
@ -862,12 +862,12 @@ static void bitmap_file_unmap(struct bitmap_storage *store)
* then it is no longer reliable, so we stop using it and we mark the file
* as failed in the superblock
*/
static void bitmap_file_kick(struct bitmap *bitmap)
static void md_bitmap_file_kick(struct bitmap *bitmap)
{
char *path, *ptr = NULL;
if (!test_and_set_bit(BITMAP_STALE, &bitmap->flags)) {
bitmap_update_sb(bitmap);
md_bitmap_update_sb(bitmap);
if (bitmap->storage.file) {
path = kmalloc(PAGE_SIZE, GFP_KERNEL);
@ -923,7 +923,7 @@ static inline int test_and_clear_page_attr(struct bitmap *bitmap, int pnum,
* we set the bit immediately, then we record the page number so that
* when an unplug occurs, we can flush the dirty pages out to disk
*/
static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
static void md_bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
{
unsigned long bit;
struct page *page;
@ -952,7 +952,7 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
set_page_attr(bitmap, page->index - node_offset, BITMAP_PAGE_DIRTY);
}
static void bitmap_file_clear_bit(struct bitmap *bitmap, sector_t block)
static void md_bitmap_file_clear_bit(struct bitmap *bitmap, sector_t block)
{
unsigned long bit;
struct page *page;
@ -980,7 +980,7 @@ static void bitmap_file_clear_bit(struct bitmap *bitmap, sector_t block)
}
}
static int bitmap_file_test_bit(struct bitmap *bitmap, sector_t block)
static int md_bitmap_file_test_bit(struct bitmap *bitmap, sector_t block)
{
unsigned long bit;
struct page *page;
@ -1005,7 +1005,7 @@ static int bitmap_file_test_bit(struct bitmap *bitmap, sector_t block)
/* this gets called when the md device is ready to unplug its underlying
* (slave) device queues -- before we let any writes go down, we need to
* sync the dirty pages of the bitmap file to disk */
void bitmap_unplug(struct bitmap *bitmap)
void md_bitmap_unplug(struct bitmap *bitmap)
{
unsigned long i;
int dirty, need_write;
@ -1025,7 +1025,7 @@ void bitmap_unplug(struct bitmap *bitmap)
BITMAP_PAGE_NEEDWRITE);
if (dirty || need_write) {
if (!writing) {
bitmap_wait_writes(bitmap);
md_bitmap_wait_writes(bitmap);
if (bitmap->mddev->queue)
blk_add_trace_msg(bitmap->mddev->queue,
"md bitmap_unplug");
@ -1036,14 +1036,14 @@ void bitmap_unplug(struct bitmap *bitmap)
}
}
if (writing)
bitmap_wait_writes(bitmap);
md_bitmap_wait_writes(bitmap);
if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags))
bitmap_file_kick(bitmap);
md_bitmap_file_kick(bitmap);
}
EXPORT_SYMBOL(bitmap_unplug);
EXPORT_SYMBOL(md_bitmap_unplug);
static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed);
static void md_bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed);
/* * bitmap_init_from_disk -- called at bitmap_create time to initialize
* the in-memory bitmap from the on-disk bitmap -- also, sets up the
* memory mapping of the bitmap file
@ -1055,7 +1055,7 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n
* We ignore all bits for sectors that end earlier than 'start'.
* This is used when reading an out-of-date bitmap...
*/
static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
static int md_bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
{
unsigned long i, chunks, index, oldindex, bit, node_offset = 0;
struct page *page = NULL;
@ -1078,9 +1078,9 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
/* if the disk bit is set, set the memory bit */
int needed = ((sector_t)(i+1) << (bitmap->counts.chunkshift)
>= start);
bitmap_set_memory_bits(bitmap,
(sector_t)i << bitmap->counts.chunkshift,
needed);
md_bitmap_set_memory_bits(bitmap,
(sector_t)i << bitmap->counts.chunkshift,
needed);
}
return 0;
}
@ -1159,9 +1159,9 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
/* if the disk bit is set, set the memory bit */
int needed = ((sector_t)(i+1) << bitmap->counts.chunkshift
>= start);
bitmap_set_memory_bits(bitmap,
(sector_t)i << bitmap->counts.chunkshift,
needed);
md_bitmap_set_memory_bits(bitmap,
(sector_t)i << bitmap->counts.chunkshift,
needed);
bit_cnt++;
}
offset = 0;
@ -1179,7 +1179,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
return ret;
}
void bitmap_write_all(struct bitmap *bitmap)
void md_bitmap_write_all(struct bitmap *bitmap)
{
/* We don't actually write all bitmap blocks here,
* just flag them as needing to be written
@ -1198,16 +1198,16 @@ void bitmap_write_all(struct bitmap *bitmap)
bitmap->allclean = 0;
}
static void bitmap_count_page(struct bitmap_counts *bitmap,
sector_t offset, int inc)
static void md_bitmap_count_page(struct bitmap_counts *bitmap,
sector_t offset, int inc)
{
sector_t chunk = offset >> bitmap->chunkshift;
unsigned long page = chunk >> PAGE_COUNTER_SHIFT;
bitmap->bp[page].count += inc;
bitmap_checkfree(bitmap, page);
md_bitmap_checkfree(bitmap, page);
}
static void bitmap_set_pending(struct bitmap_counts *bitmap, sector_t offset)
static void md_bitmap_set_pending(struct bitmap_counts *bitmap, sector_t offset)
{
sector_t chunk = offset >> bitmap->chunkshift;
unsigned long page = chunk >> PAGE_COUNTER_SHIFT;
@ -1217,16 +1217,16 @@ static void bitmap_set_pending(struct bitmap_counts *bitmap, sector_t offset)
bp->pending = 1;
}
static bitmap_counter_t *bitmap_get_counter(struct bitmap_counts *bitmap,
sector_t offset, sector_t *blocks,
int create);
static bitmap_counter_t *md_bitmap_get_counter(struct bitmap_counts *bitmap,
sector_t offset, sector_t *blocks,
int create);
/*
* bitmap daemon -- periodically wakes up to clean bits and flush pages
* out to disk
*/
void bitmap_daemon_work(struct mddev *mddev)
void md_bitmap_daemon_work(struct mddev *mddev)
{
struct bitmap *bitmap;
unsigned long j;
@ -1301,10 +1301,8 @@ void bitmap_daemon_work(struct mddev *mddev)
}
counts->bp[j >> PAGE_COUNTER_SHIFT].pending = 0;
}
bmc = bitmap_get_counter(counts,
block,
&blocks, 0);
bmc = md_bitmap_get_counter(counts, block, &blocks, 0);
if (!bmc) {
j |= PAGE_COUNTER_MASK;
continue;
@ -1312,17 +1310,17 @@ void bitmap_daemon_work(struct mddev *mddev)
if (*bmc == 1 && !bitmap->need_sync) {
/* We can clear the bit */
*bmc = 0;
bitmap_count_page(counts, block, -1);
bitmap_file_clear_bit(bitmap, block);
md_bitmap_count_page(counts, block, -1);
md_bitmap_file_clear_bit(bitmap, block);
} else if (*bmc && *bmc <= 2) {
*bmc = 1;
bitmap_set_pending(counts, block);
md_bitmap_set_pending(counts, block);
bitmap->allclean = 0;
}
}
spin_unlock_irq(&counts->lock);
bitmap_wait_writes(bitmap);
md_bitmap_wait_writes(bitmap);
/* Now start writeout on any page in NEEDWRITE that isn't DIRTY.
* DIRTY pages need to be written by bitmap_unplug so it can wait
* for them.
@ -1352,9 +1350,9 @@ void bitmap_daemon_work(struct mddev *mddev)
mutex_unlock(&mddev->bitmap_info.mutex);
}
static bitmap_counter_t *bitmap_get_counter(struct bitmap_counts *bitmap,
sector_t offset, sector_t *blocks,
int create)
static bitmap_counter_t *md_bitmap_get_counter(struct bitmap_counts *bitmap,
sector_t offset, sector_t *blocks,
int create)
__releases(bitmap->lock)
__acquires(bitmap->lock)
{
@ -1368,7 +1366,7 @@ __acquires(bitmap->lock)
sector_t csize;
int err;
err = bitmap_checkpage(bitmap, page, create, 0);
err = md_bitmap_checkpage(bitmap, page, create, 0);
if (bitmap->bp[page].hijacked ||
bitmap->bp[page].map == NULL)
@ -1394,7 +1392,7 @@ __acquires(bitmap->lock)
&(bitmap->bp[page].map[pageoff]);
}
int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int behind)
int md_bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int behind)
{
if (!bitmap)
return 0;
@ -1415,7 +1413,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
bitmap_counter_t *bmc;
spin_lock_irq(&bitmap->counts.lock);
bmc = bitmap_get_counter(&bitmap->counts, offset, &blocks, 1);
bmc = md_bitmap_get_counter(&bitmap->counts, offset, &blocks, 1);
if (!bmc) {
spin_unlock_irq(&bitmap->counts.lock);
return 0;
@ -1437,8 +1435,8 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
switch (*bmc) {
case 0:
bitmap_file_set_bit(bitmap, offset);
bitmap_count_page(&bitmap->counts, offset, 1);
md_bitmap_file_set_bit(bitmap, offset);
md_bitmap_count_page(&bitmap->counts, offset, 1);
/* fall through */
case 1:
*bmc = 2;
@ -1456,10 +1454,10 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
}
return 0;
}
EXPORT_SYMBOL(bitmap_startwrite);
EXPORT_SYMBOL(md_bitmap_startwrite);
void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors,
int success, int behind)
void md_bitmap_endwrite(struct bitmap *bitmap, sector_t offset,
unsigned long sectors, int success, int behind)
{
if (!bitmap)
return;
@ -1477,7 +1475,7 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
bitmap_counter_t *bmc;
spin_lock_irqsave(&bitmap->counts.lock, flags);
bmc = bitmap_get_counter(&bitmap->counts, offset, &blocks, 0);
bmc = md_bitmap_get_counter(&bitmap->counts, offset, &blocks, 0);
if (!bmc) {
spin_unlock_irqrestore(&bitmap->counts.lock, flags);
return;
@ -1498,7 +1496,7 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
(*bmc)--;
if (*bmc <= 2) {
bitmap_set_pending(&bitmap->counts, offset);
md_bitmap_set_pending(&bitmap->counts, offset);
bitmap->allclean = 0;
}
spin_unlock_irqrestore(&bitmap->counts.lock, flags);
@ -1509,7 +1507,7 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
sectors = 0;
}
}
EXPORT_SYMBOL(bitmap_endwrite);
EXPORT_SYMBOL(md_bitmap_endwrite);
static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks,
int degraded)
@ -1521,7 +1519,7 @@ static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t
return 1; /* always resync if no bitmap */
}
spin_lock_irq(&bitmap->counts.lock);
bmc = bitmap_get_counter(&bitmap->counts, offset, blocks, 0);
bmc = md_bitmap_get_counter(&bitmap->counts, offset, blocks, 0);
rv = 0;
if (bmc) {
/* locked */
@ -1539,8 +1537,8 @@ static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t
return rv;
}
int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks,
int degraded)
int md_bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks,
int degraded)
{
/* bitmap_start_sync must always report on multiples of whole
* pages, otherwise resync (which is very PAGE_SIZE based) will
@ -1561,9 +1559,9 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks,
}
return rv;
}
EXPORT_SYMBOL(bitmap_start_sync);
EXPORT_SYMBOL(md_bitmap_start_sync);
void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted)
void md_bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted)
{
bitmap_counter_t *bmc;
unsigned long flags;
@ -1573,7 +1571,7 @@ void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, i
return;
}
spin_lock_irqsave(&bitmap->counts.lock, flags);
bmc = bitmap_get_counter(&bitmap->counts, offset, blocks, 0);
bmc = md_bitmap_get_counter(&bitmap->counts, offset, blocks, 0);
if (bmc == NULL)
goto unlock;
/* locked */
@ -1584,7 +1582,7 @@ void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, i
*bmc |= NEEDED_MASK;
else {
if (*bmc <= 2) {
bitmap_set_pending(&bitmap->counts, offset);
md_bitmap_set_pending(&bitmap->counts, offset);
bitmap->allclean = 0;
}
}
@ -1592,9 +1590,9 @@ void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, i
unlock:
spin_unlock_irqrestore(&bitmap->counts.lock, flags);
}
EXPORT_SYMBOL(bitmap_end_sync);
EXPORT_SYMBOL(md_bitmap_end_sync);
void bitmap_close_sync(struct bitmap *bitmap)
void md_bitmap_close_sync(struct bitmap *bitmap)
{
/* Sync has finished, and any bitmap chunks that weren't synced
* properly have been aborted. It remains to us to clear the
@ -1605,13 +1603,13 @@ void bitmap_close_sync(struct bitmap *bitmap)
if (!bitmap)
return;
while (sector < bitmap->mddev->resync_max_sectors) {
bitmap_end_sync(bitmap, sector, &blocks, 0);
md_bitmap_end_sync(bitmap, sector, &blocks, 0);
sector += blocks;
}
}
EXPORT_SYMBOL(bitmap_close_sync);
EXPORT_SYMBOL(md_bitmap_close_sync);
void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force)
void md_bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force)
{
sector_t s = 0;
sector_t blocks;
@ -1633,15 +1631,15 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force)
sector &= ~((1ULL << bitmap->counts.chunkshift) - 1);
s = 0;
while (s < sector && s < bitmap->mddev->resync_max_sectors) {
bitmap_end_sync(bitmap, s, &blocks, 0);
md_bitmap_end_sync(bitmap, s, &blocks, 0);
s += blocks;
}
bitmap->last_end_sync = jiffies;
sysfs_notify(&bitmap->mddev->kobj, NULL, "sync_completed");
}
EXPORT_SYMBOL(bitmap_cond_end_sync);
EXPORT_SYMBOL(md_bitmap_cond_end_sync);
void bitmap_sync_with_cluster(struct mddev *mddev,
void md_bitmap_sync_with_cluster(struct mddev *mddev,
sector_t old_lo, sector_t old_hi,
sector_t new_lo, sector_t new_hi)
{
@ -1649,20 +1647,20 @@ void bitmap_sync_with_cluster(struct mddev *mddev,
sector_t sector, blocks = 0;
for (sector = old_lo; sector < new_lo; ) {
bitmap_end_sync(bitmap, sector, &blocks, 0);
md_bitmap_end_sync(bitmap, sector, &blocks, 0);
sector += blocks;
}
WARN((blocks > new_lo) && old_lo, "alignment is not correct for lo\n");
for (sector = old_hi; sector < new_hi; ) {
bitmap_start_sync(bitmap, sector, &blocks, 0);
md_bitmap_start_sync(bitmap, sector, &blocks, 0);
sector += blocks;
}
WARN((blocks > new_hi) && old_hi, "alignment is not correct for hi\n");
}
EXPORT_SYMBOL(bitmap_sync_with_cluster);
EXPORT_SYMBOL(md_bitmap_sync_with_cluster);
static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
static void md_bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
{
/* For each chunk covered by any of these sectors, set the
* counter to 2 and possibly set resync_needed. They should all
@ -1672,15 +1670,15 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n
sector_t secs;
bitmap_counter_t *bmc;
spin_lock_irq(&bitmap->counts.lock);
bmc = bitmap_get_counter(&bitmap->counts, offset, &secs, 1);
bmc = md_bitmap_get_counter(&bitmap->counts, offset, &secs, 1);
if (!bmc) {
spin_unlock_irq(&bitmap->counts.lock);
return;
}
if (!*bmc) {
*bmc = 2;
bitmap_count_page(&bitmap->counts, offset, 1);
bitmap_set_pending(&bitmap->counts, offset);
md_bitmap_count_page(&bitmap->counts, offset, 1);
md_bitmap_set_pending(&bitmap->counts, offset);
bitmap->allclean = 0;
}
if (needed)
@ -1689,14 +1687,14 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n
}
/* dirty the memory and file bits for bitmap chunks "s" to "e" */
void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e)
void md_bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e)
{
unsigned long chunk;
for (chunk = s; chunk <= e; chunk++) {
sector_t sec = (sector_t)chunk << bitmap->counts.chunkshift;
bitmap_set_memory_bits(bitmap, sec, 1);
bitmap_file_set_bit(bitmap, sec);
md_bitmap_set_memory_bits(bitmap, sec, 1);
md_bitmap_file_set_bit(bitmap, sec);
if (sec < bitmap->mddev->recovery_cp)
/* We are asserting that the array is dirty,
* so move the recovery_cp address back so
@ -1709,7 +1707,7 @@ void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e)
/*
* flush out any pending updates
*/
void bitmap_flush(struct mddev *mddev)
void md_bitmap_flush(struct mddev *mddev)
{
struct bitmap *bitmap = mddev->bitmap;
long sleep;
@ -1722,18 +1720,18 @@ void bitmap_flush(struct mddev *mddev)
*/
sleep = mddev->bitmap_info.daemon_sleep * 2;
bitmap->daemon_lastrun -= sleep;
bitmap_daemon_work(mddev);
md_bitmap_daemon_work(mddev);
bitmap->daemon_lastrun -= sleep;
bitmap_daemon_work(mddev);
md_bitmap_daemon_work(mddev);
bitmap->daemon_lastrun -= sleep;
bitmap_daemon_work(mddev);
bitmap_update_sb(bitmap);
md_bitmap_daemon_work(mddev);
md_bitmap_update_sb(bitmap);
}
/*
* free memory that was allocated
*/
void bitmap_free(struct bitmap *bitmap)
void md_bitmap_free(struct bitmap *bitmap)
{
unsigned long k, pages;
struct bitmap_page *bp;
@ -1753,7 +1751,7 @@ void bitmap_free(struct bitmap *bitmap)
atomic_read(&bitmap->pending_writes) == 0);
/* release the bitmap file */
bitmap_file_unmap(&bitmap->storage);
md_bitmap_file_unmap(&bitmap->storage);
bp = bitmap->counts.bp;
pages = bitmap->counts.pages;
@ -1767,9 +1765,9 @@ void bitmap_free(struct bitmap *bitmap)
kfree(bp);
kfree(bitmap);
}
EXPORT_SYMBOL(bitmap_free);
EXPORT_SYMBOL(md_bitmap_free);
void bitmap_wait_behind_writes(struct mddev *mddev)
void md_bitmap_wait_behind_writes(struct mddev *mddev)
{
struct bitmap *bitmap = mddev->bitmap;
@ -1783,14 +1781,14 @@ void bitmap_wait_behind_writes(struct mddev *mddev)
}
}
void bitmap_destroy(struct mddev *mddev)
void md_bitmap_destroy(struct mddev *mddev)
{
struct bitmap *bitmap = mddev->bitmap;
if (!bitmap) /* there was no bitmap */
return;
bitmap_wait_behind_writes(mddev);
md_bitmap_wait_behind_writes(mddev);
mutex_lock(&mddev->bitmap_info.mutex);
spin_lock(&mddev->lock);
@ -1800,7 +1798,7 @@ void bitmap_destroy(struct mddev *mddev)
if (mddev->thread)
mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
bitmap_free(bitmap);
md_bitmap_free(bitmap);
}
/*
@ -1808,7 +1806,7 @@ void bitmap_destroy(struct mddev *mddev)
* if this returns an error, bitmap_destroy must be called to do clean up
* once mddev->bitmap is set
*/
struct bitmap *bitmap_create(struct mddev *mddev, int slot)
struct bitmap *md_bitmap_create(struct mddev *mddev, int slot)
{
struct bitmap *bitmap;
sector_t blocks = mddev->resync_max_sectors;
@ -1863,9 +1861,9 @@ struct bitmap *bitmap_create(struct mddev *mddev, int slot)
* instructing us to create a new on-disk bitmap instance.
*/
if (test_and_clear_bit(MD_ARRAY_FIRST_USE, &mddev->flags))
err = bitmap_new_disk_sb(bitmap);
err = md_bitmap_new_disk_sb(bitmap);
else
err = bitmap_read_sb(bitmap);
err = md_bitmap_read_sb(bitmap);
} else {
err = 0;
if (mddev->bitmap_info.chunksize == 0 ||
@ -1878,7 +1876,7 @@ struct bitmap *bitmap_create(struct mddev *mddev, int slot)
goto error;
bitmap->daemon_lastrun = jiffies;
err = bitmap_resize(bitmap, blocks, mddev->bitmap_info.chunksize, 1);
err = md_bitmap_resize(bitmap, blocks, mddev->bitmap_info.chunksize, 1);
if (err)
goto error;
@ -1891,11 +1889,11 @@ struct bitmap *bitmap_create(struct mddev *mddev, int slot)
return bitmap;
error:
bitmap_free(bitmap);
md_bitmap_free(bitmap);
return ERR_PTR(err);
}
int bitmap_load(struct mddev *mddev)
int md_bitmap_load(struct mddev *mddev)
{
int err = 0;
sector_t start = 0;
@ -1915,10 +1913,10 @@ int bitmap_load(struct mddev *mddev)
*/
while (sector < mddev->resync_max_sectors) {
sector_t blocks;
bitmap_start_sync(bitmap, sector, &blocks, 0);
md_bitmap_start_sync(bitmap, sector, &blocks, 0);
sector += blocks;
}
bitmap_close_sync(bitmap);
md_bitmap_close_sync(bitmap);
if (mddev->degraded == 0
|| bitmap->events_cleared == mddev->events)
@ -1927,7 +1925,7 @@ int bitmap_load(struct mddev *mddev)
start = mddev->recovery_cp;
mutex_lock(&mddev->bitmap_info.mutex);
err = bitmap_init_from_disk(bitmap, start);
err = md_bitmap_init_from_disk(bitmap, start);
mutex_unlock(&mddev->bitmap_info.mutex);
if (err)
@ -1940,29 +1938,29 @@ int bitmap_load(struct mddev *mddev)
mddev->thread->timeout = mddev->bitmap_info.daemon_sleep;
md_wakeup_thread(mddev->thread);
bitmap_update_sb(bitmap);
md_bitmap_update_sb(bitmap);
if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags))
err = -EIO;
out:
return err;
}
EXPORT_SYMBOL_GPL(bitmap_load);
EXPORT_SYMBOL_GPL(md_bitmap_load);
struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot)
{
int rv = 0;
struct bitmap *bitmap;
bitmap = bitmap_create(mddev, slot);
bitmap = md_bitmap_create(mddev, slot);
if (IS_ERR(bitmap)) {
rv = PTR_ERR(bitmap);
return ERR_PTR(rv);
}
rv = bitmap_init_from_disk(bitmap, 0);
rv = md_bitmap_init_from_disk(bitmap, 0);
if (rv) {
bitmap_free(bitmap);
md_bitmap_free(bitmap);
return ERR_PTR(rv);
}
@ -1973,7 +1971,7 @@ EXPORT_SYMBOL(get_bitmap_from_slot);
/* Loads the bitmap associated with slot and copies the resync information
* to our bitmap
*/
int bitmap_copy_from_slot(struct mddev *mddev, int slot,
int md_bitmap_copy_from_slot(struct mddev *mddev, int slot,
sector_t *low, sector_t *high, bool clear_bits)
{
int rv = 0, i, j;
@ -1990,35 +1988,35 @@ int bitmap_copy_from_slot(struct mddev *mddev, int slot,
counts = &bitmap->counts;
for (j = 0; j < counts->chunks; j++) {
block = (sector_t)j << counts->chunkshift;
if (bitmap_file_test_bit(bitmap, block)) {
if (md_bitmap_file_test_bit(bitmap, block)) {
if (!lo)
lo = block;
hi = block;
bitmap_file_clear_bit(bitmap, block);
bitmap_set_memory_bits(mddev->bitmap, block, 1);
bitmap_file_set_bit(mddev->bitmap, block);
md_bitmap_file_clear_bit(bitmap, block);
md_bitmap_set_memory_bits(mddev->bitmap, block, 1);
md_bitmap_file_set_bit(mddev->bitmap, block);
}
}
if (clear_bits) {
bitmap_update_sb(bitmap);
md_bitmap_update_sb(bitmap);
/* BITMAP_PAGE_PENDING is set, but bitmap_unplug needs
* BITMAP_PAGE_DIRTY or _NEEDWRITE to write ... */
for (i = 0; i < bitmap->storage.file_pages; i++)
if (test_page_attr(bitmap, i, BITMAP_PAGE_PENDING))
set_page_attr(bitmap, i, BITMAP_PAGE_NEEDWRITE);
bitmap_unplug(bitmap);
md_bitmap_unplug(bitmap);
}
bitmap_unplug(mddev->bitmap);
md_bitmap_unplug(mddev->bitmap);
*low = lo;
*high = hi;
return rv;
}
EXPORT_SYMBOL_GPL(bitmap_copy_from_slot);
EXPORT_SYMBOL_GPL(md_bitmap_copy_from_slot);
void bitmap_status(struct seq_file *seq, struct bitmap *bitmap)
void md_bitmap_status(struct seq_file *seq, struct bitmap *bitmap)
{
unsigned long chunk_kb;
struct bitmap_counts *counts;
@ -2045,7 +2043,7 @@ void bitmap_status(struct seq_file *seq, struct bitmap *bitmap)
seq_printf(seq, "\n");
}
int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
int chunksize, int init)
{
/* If chunk_size is 0, choose an appropriate chunk size.
@ -2106,12 +2104,12 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
chunks = DIV_ROUND_UP_SECTOR_T(blocks, 1 << chunkshift);
memset(&store, 0, sizeof(store));
if (bitmap->mddev->bitmap_info.offset || bitmap->mddev->bitmap_info.file)
ret = bitmap_storage_alloc(&store, chunks,
!bitmap->mddev->bitmap_info.external,
mddev_is_clustered(bitmap->mddev)
? bitmap->cluster_slot : 0);
ret = md_bitmap_storage_alloc(&store, chunks,
!bitmap->mddev->bitmap_info.external,
mddev_is_clustered(bitmap->mddev)
? bitmap->cluster_slot : 0);
if (ret) {
bitmap_file_unmap(&store);
md_bitmap_file_unmap(&store);
goto err;
}
@ -2120,7 +2118,7 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
new_bp = kcalloc(pages, sizeof(*new_bp), GFP_KERNEL);
ret = -ENOMEM;
if (!new_bp) {
bitmap_file_unmap(&store);
md_bitmap_file_unmap(&store);
goto err;
}
@ -2134,7 +2132,7 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
memcpy(page_address(store.sb_page),
page_address(bitmap->storage.sb_page),
sizeof(bitmap_super_t));
bitmap_file_unmap(&bitmap->storage);
md_bitmap_file_unmap(&bitmap->storage);
bitmap->storage = store;
old_counts = bitmap->counts;
@ -2154,7 +2152,7 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
if (mddev_is_clustered(bitmap->mddev)) {
unsigned long page;
for (page = 0; page < pages; page++) {
ret = bitmap_checkpage(&bitmap->counts, page, 1, 1);
ret = md_bitmap_checkpage(&bitmap->counts, page, 1, 1);
if (ret) {
unsigned long k;
@ -2184,27 +2182,23 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
bitmap_counter_t *bmc_old, *bmc_new;
int set;
bmc_old = bitmap_get_counter(&old_counts, block,
&old_blocks, 0);
bmc_old = md_bitmap_get_counter(&old_counts, block, &old_blocks, 0);
set = bmc_old && NEEDED(*bmc_old);
if (set) {
bmc_new = bitmap_get_counter(&bitmap->counts, block,
&new_blocks, 1);
bmc_new = md_bitmap_get_counter(&bitmap->counts, block, &new_blocks, 1);
if (*bmc_new == 0) {
/* need to set on-disk bits too. */
sector_t end = block + new_blocks;
sector_t start = block >> chunkshift;
start <<= chunkshift;
while (start < end) {
bitmap_file_set_bit(bitmap, block);
md_bitmap_file_set_bit(bitmap, block);
start += 1 << chunkshift;
}
*bmc_new = 2;
bitmap_count_page(&bitmap->counts,
block, 1);
bitmap_set_pending(&bitmap->counts,
block);
md_bitmap_count_page(&bitmap->counts, block, 1);
md_bitmap_set_pending(&bitmap->counts, block);
}
*bmc_new |= NEEDED_MASK;
if (new_blocks < old_blocks)
@ -2225,18 +2219,15 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
int i;
while (block < (chunks << chunkshift)) {
bitmap_counter_t *bmc;
bmc = bitmap_get_counter(&bitmap->counts, block,
&new_blocks, 1);
bmc = md_bitmap_get_counter(&bitmap->counts, block, &new_blocks, 1);
if (bmc) {
/* new space. It needs to be resynced, so
* we set NEEDED_MASK.
*/
if (*bmc == 0) {
*bmc = NEEDED_MASK | 2;
bitmap_count_page(&bitmap->counts,
block, 1);
bitmap_set_pending(&bitmap->counts,
block);
md_bitmap_count_page(&bitmap->counts, block, 1);
md_bitmap_set_pending(&bitmap->counts, block);
}
}
block += new_blocks;
@ -2247,14 +2238,14 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
spin_unlock_irq(&bitmap->counts.lock);
if (!init) {
bitmap_unplug(bitmap);
md_bitmap_unplug(bitmap);
bitmap->mddev->pers->quiesce(bitmap->mddev, 0);
}
ret = 0;
err:
return ret;
}
EXPORT_SYMBOL_GPL(bitmap_resize);
EXPORT_SYMBOL_GPL(md_bitmap_resize);
static ssize_t
location_show(struct mddev *mddev, char *page)
@ -2298,7 +2289,7 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
}
if (mddev->pers) {
mddev->pers->quiesce(mddev, 1);
bitmap_destroy(mddev);
md_bitmap_destroy(mddev);
mddev->pers->quiesce(mddev, 0);
}
mddev->bitmap_info.offset = 0;
@ -2337,18 +2328,18 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
if (mddev->pers) {
struct bitmap *bitmap;
mddev->pers->quiesce(mddev, 1);
bitmap = bitmap_create(mddev, -1);
bitmap = md_bitmap_create(mddev, -1);
if (IS_ERR(bitmap))
rv = PTR_ERR(bitmap);
else {
mddev->bitmap = bitmap;
rv = bitmap_load(mddev);
rv = md_bitmap_load(mddev);
if (rv)
mddev->bitmap_info.offset = 0;
}
mddev->pers->quiesce(mddev, 0);
if (rv) {
bitmap_destroy(mddev);
md_bitmap_destroy(mddev);
goto out;
}
}

View File

@ -236,43 +236,43 @@ struct bitmap {
/* the bitmap API */
/* these are used only by md/bitmap */
struct bitmap *bitmap_create(struct mddev *mddev, int slot);
int bitmap_load(struct mddev *mddev);
void bitmap_flush(struct mddev *mddev);
void bitmap_destroy(struct mddev *mddev);
struct bitmap *md_bitmap_create(struct mddev *mddev, int slot);
int md_bitmap_load(struct mddev *mddev);
void md_bitmap_flush(struct mddev *mddev);
void md_bitmap_destroy(struct mddev *mddev);
void bitmap_print_sb(struct bitmap *bitmap);
void bitmap_update_sb(struct bitmap *bitmap);
void bitmap_status(struct seq_file *seq, struct bitmap *bitmap);
void md_bitmap_print_sb(struct bitmap *bitmap);
void md_bitmap_update_sb(struct bitmap *bitmap);
void md_bitmap_status(struct seq_file *seq, struct bitmap *bitmap);
int bitmap_setallbits(struct bitmap *bitmap);
void bitmap_write_all(struct bitmap *bitmap);
int md_bitmap_setallbits(struct bitmap *bitmap);
void md_bitmap_write_all(struct bitmap *bitmap);
void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e);
void md_bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e);
/* these are exported */
int bitmap_startwrite(struct bitmap *bitmap, sector_t offset,
unsigned long sectors, int behind);
void bitmap_endwrite(struct bitmap *bitmap, sector_t offset,
int md_bitmap_startwrite(struct bitmap *bitmap, sector_t offset,
unsigned long sectors, int behind);
void md_bitmap_endwrite(struct bitmap *bitmap, sector_t offset,
unsigned long sectors, int success, int behind);
int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int degraded);
void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted);
void bitmap_close_sync(struct bitmap *bitmap);
void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force);
void bitmap_sync_with_cluster(struct mddev *mddev,
sector_t old_lo, sector_t old_hi,
sector_t new_lo, sector_t new_hi);
int md_bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int degraded);
void md_bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted);
void md_bitmap_close_sync(struct bitmap *bitmap);
void md_bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force);
void md_bitmap_sync_with_cluster(struct mddev *mddev,
sector_t old_lo, sector_t old_hi,
sector_t new_lo, sector_t new_hi);
void bitmap_unplug(struct bitmap *bitmap);
void bitmap_daemon_work(struct mddev *mddev);
void md_bitmap_unplug(struct bitmap *bitmap);
void md_bitmap_daemon_work(struct mddev *mddev);
int bitmap_resize(struct bitmap *bitmap, sector_t blocks,
int chunksize, int init);
int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
int chunksize, int init);
struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot);
int bitmap_copy_from_slot(struct mddev *mddev, int slot,
sector_t *lo, sector_t *hi, bool clear_bits);
void bitmap_free(struct bitmap *bitmap);
void bitmap_wait_behind_writes(struct mddev *mddev);
int md_bitmap_copy_from_slot(struct mddev *mddev, int slot,
sector_t *lo, sector_t *hi, bool clear_bits);
void md_bitmap_free(struct bitmap *bitmap);
void md_bitmap_wait_behind_writes(struct mddev *mddev);
#endif
#endif

View File

@ -317,7 +317,7 @@ static void recover_bitmaps(struct md_thread *thread)
str, ret);
goto clear_bit;
}
ret = bitmap_copy_from_slot(mddev, slot, &lo, &hi, true);
ret = md_bitmap_copy_from_slot(mddev, slot, &lo, &hi, true);
if (ret) {
pr_err("md-cluster: Could not copy data from bitmap %d\n", slot);
goto clear_bit;
@ -492,9 +492,7 @@ static void process_suspend_info(struct mddev *mddev,
* resync thread is running in another node,
* so we don't need to do the resync again
* with the same section */
bitmap_sync_with_cluster(mddev, cinfo->sync_low,
cinfo->sync_hi,
lo, hi);
md_bitmap_sync_with_cluster(mddev, cinfo->sync_low, cinfo->sync_hi, lo, hi);
cinfo->sync_low = lo;
cinfo->sync_hi = hi;
@ -842,7 +840,7 @@ static int gather_all_resync_info(struct mddev *mddev, int total_slots)
}
/* Read the disk bitmap sb and check if it needs recovery */
ret = bitmap_copy_from_slot(mddev, i, &lo, &hi, false);
ret = md_bitmap_copy_from_slot(mddev, i, &lo, &hi, false);
if (ret) {
pr_warn("md-cluster: Could not gather bitmaps from slot %d", i);
lockres_free(bm_lockres);
@ -1140,13 +1138,13 @@ static int cluster_check_sync_size(struct mddev *mddev)
bm_lockres = lockres_init(mddev, str, NULL, 1);
if (!bm_lockres) {
pr_err("md-cluster: Cannot initialize %s\n", str);
bitmap_free(bitmap);
md_bitmap_free(bitmap);
return -1;
}
bm_lockres->flags |= DLM_LKF_NOQUEUE;
rv = dlm_lock_sync(bm_lockres, DLM_LOCK_PW);
if (!rv)
bitmap_update_sb(bitmap);
md_bitmap_update_sb(bitmap);
lockres_free(bm_lockres);
sb = kmap_atomic(bitmap->storage.sb_page);
@ -1154,11 +1152,11 @@ static int cluster_check_sync_size(struct mddev *mddev)
sync_size = sb->sync_size;
else if (sync_size != sb->sync_size) {
kunmap_atomic(sb);
bitmap_free(bitmap);
md_bitmap_free(bitmap);
return -1;
}
kunmap_atomic(sb);
bitmap_free(bitmap);
md_bitmap_free(bitmap);
}
return (my_sync_size == sync_size) ? 0 : -1;
@ -1465,7 +1463,7 @@ static int gather_bitmaps(struct md_rdev *rdev)
for (sn = 0; sn < mddev->bitmap_info.nodes; sn++) {
if (sn == (cinfo->slot_number - 1))
continue;
err = bitmap_copy_from_slot(mddev, sn, &lo, &hi, false);
err = md_bitmap_copy_from_slot(mddev, sn, &lo, &hi, false);
if (err) {
pr_warn("md-cluster: Could not gather bitmaps from slot %d", sn);
goto out;

View File

@ -2568,7 +2568,7 @@ void md_update_sb(struct mddev *mddev, int force_change)
if (mddev->queue)
blk_add_trace_msg(mddev->queue, "md md_update_sb");
rewrite:
bitmap_update_sb(mddev->bitmap);
md_bitmap_update_sb(mddev->bitmap);
rdev_for_each(rdev, mddev) {
char b[BDEVNAME_SIZE];
@ -4381,10 +4381,10 @@ bitmap_store(struct mddev *mddev, const char *buf, size_t len)
if (buf == end) break;
}
if (*end && !isspace(*end)) break;
bitmap_dirty_bits(mddev->bitmap, chunk, end_chunk);
md_bitmap_dirty_bits(mddev->bitmap, chunk, end_chunk);
buf = skip_spaces(end);
}
bitmap_unplug(mddev->bitmap); /* flush the bits to disk */
md_bitmap_unplug(mddev->bitmap); /* flush the bits to disk */
out:
mddev_unlock(mddev);
return len;
@ -5612,7 +5612,7 @@ int md_run(struct mddev *mddev)
(mddev->bitmap_info.file || mddev->bitmap_info.offset)) {
struct bitmap *bitmap;
bitmap = bitmap_create(mddev, -1);
bitmap = md_bitmap_create(mddev, -1);
if (IS_ERR(bitmap)) {
err = PTR_ERR(bitmap);
pr_warn("%s: failed to create bitmap (%d)\n",
@ -5627,7 +5627,7 @@ int md_run(struct mddev *mddev)
pers->free(mddev, mddev->private);
mddev->private = NULL;
module_put(pers->owner);
bitmap_destroy(mddev);
md_bitmap_destroy(mddev);
goto abort;
}
if (mddev->queue) {
@ -5712,9 +5712,9 @@ static int do_md_run(struct mddev *mddev)
err = md_run(mddev);
if (err)
goto out;
err = bitmap_load(mddev);
err = md_bitmap_load(mddev);
if (err) {
bitmap_destroy(mddev);
md_bitmap_destroy(mddev);
goto out;
}
@ -5856,7 +5856,7 @@ static void __md_stop_writes(struct mddev *mddev)
mddev->pers->quiesce(mddev, 1);
mddev->pers->quiesce(mddev, 0);
}
bitmap_flush(mddev);
md_bitmap_flush(mddev);
if (mddev->ro == 0 &&
((!mddev->in_sync && !mddev_is_clustered(mddev)) ||
@ -5878,7 +5878,7 @@ EXPORT_SYMBOL_GPL(md_stop_writes);
static void mddev_detach(struct mddev *mddev)
{
bitmap_wait_behind_writes(mddev);
md_bitmap_wait_behind_writes(mddev);
if (mddev->pers && mddev->pers->quiesce) {
mddev->pers->quiesce(mddev, 1);
mddev->pers->quiesce(mddev, 0);
@ -5891,7 +5891,7 @@ static void mddev_detach(struct mddev *mddev)
static void __md_stop(struct mddev *mddev)
{
struct md_personality *pers = mddev->pers;
bitmap_destroy(mddev);
md_bitmap_destroy(mddev);
mddev_detach(mddev);
/* Ensure ->event_work is done */
flush_workqueue(md_misc_wq);
@ -6710,21 +6710,21 @@ static int set_bitmap_file(struct mddev *mddev, int fd)
if (fd >= 0) {
struct bitmap *bitmap;
bitmap = bitmap_create(mddev, -1);
bitmap = md_bitmap_create(mddev, -1);
mddev_suspend(mddev);
if (!IS_ERR(bitmap)) {
mddev->bitmap = bitmap;
err = bitmap_load(mddev);
err = md_bitmap_load(mddev);
} else
err = PTR_ERR(bitmap);
if (err) {
bitmap_destroy(mddev);
md_bitmap_destroy(mddev);
fd = -1;
}
mddev_resume(mddev);
} else if (fd < 0) {
mddev_suspend(mddev);
bitmap_destroy(mddev);
md_bitmap_destroy(mddev);
mddev_resume(mddev);
}
}
@ -7010,15 +7010,15 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info)
mddev->bitmap_info.default_offset;
mddev->bitmap_info.space =
mddev->bitmap_info.default_space;
bitmap = bitmap_create(mddev, -1);
bitmap = md_bitmap_create(mddev, -1);
mddev_suspend(mddev);
if (!IS_ERR(bitmap)) {
mddev->bitmap = bitmap;
rv = bitmap_load(mddev);
rv = md_bitmap_load(mddev);
} else
rv = PTR_ERR(bitmap);
if (rv)
bitmap_destroy(mddev);
md_bitmap_destroy(mddev);
mddev_resume(mddev);
} else {
/* remove the bitmap */
@ -7043,7 +7043,7 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info)
md_cluster_ops->leave(mddev);
}
mddev_suspend(mddev);
bitmap_destroy(mddev);
md_bitmap_destroy(mddev);
mddev_resume(mddev);
mddev->bitmap_info.offset = 0;
}
@ -7923,7 +7923,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
} else
seq_printf(seq, "\n ");
bitmap_status(seq, mddev->bitmap);
md_bitmap_status(seq, mddev->bitmap);
seq_printf(seq, "\n");
}
@ -8794,7 +8794,7 @@ void md_check_recovery(struct mddev *mddev)
return;
if (mddev->bitmap)
bitmap_daemon_work(mddev);
md_bitmap_daemon_work(mddev);
if (signal_pending(current)) {
if (mddev->pers->sync_request && !mddev->external) {
@ -8931,7 +8931,7 @@ void md_check_recovery(struct mddev *mddev)
* which has the bitmap stored on all devices.
* So make sure all bitmap pages get written
*/
bitmap_write_all(mddev->bitmap);
md_bitmap_write_all(mddev->bitmap);
}
INIT_WORK(&mddev->del_work, md_start_sync);
queue_work(md_misc_wq, &mddev->del_work);
@ -9179,7 +9179,7 @@ static void check_sb_changes(struct mddev *mddev, struct md_rdev *rdev)
if (ret)
pr_info("md-cluster: resize failed\n");
else
bitmap_update_sb(mddev->bitmap);
md_bitmap_update_sb(mddev->bitmap);
}
/* Check for change of roles in the active devices */

View File

@ -69,9 +69,9 @@ static struct dm_block_validator index_validator = {
*/
#define BITMAP_CSUM_XOR 240779
static void bitmap_prepare_for_write(struct dm_block_validator *v,
struct dm_block *b,
size_t block_size)
static void dm_bitmap_prepare_for_write(struct dm_block_validator *v,
struct dm_block *b,
size_t block_size)
{
struct disk_bitmap_header *disk_header = dm_block_data(b);
@ -81,9 +81,9 @@ static void bitmap_prepare_for_write(struct dm_block_validator *v,
BITMAP_CSUM_XOR));
}
static int bitmap_check(struct dm_block_validator *v,
struct dm_block *b,
size_t block_size)
static int dm_bitmap_check(struct dm_block_validator *v,
struct dm_block *b,
size_t block_size)
{
struct disk_bitmap_header *disk_header = dm_block_data(b);
__le32 csum_disk;
@ -108,8 +108,8 @@ static int bitmap_check(struct dm_block_validator *v,
static struct dm_block_validator dm_sm_bitmap_validator = {
.name = "sm_bitmap",
.prepare_for_write = bitmap_prepare_for_write,
.check = bitmap_check
.prepare_for_write = dm_bitmap_prepare_for_write,
.check = dm_bitmap_check,
};
/*----------------------------------------------------------------*/
@ -124,7 +124,7 @@ static void *dm_bitmap_data(struct dm_block *b)
#define WORD_MASK_HIGH 0xAAAAAAAAAAAAAAAAULL
static unsigned bitmap_word_used(void *addr, unsigned b)
static unsigned dm_bitmap_word_used(void *addr, unsigned b)
{
__le64 *words_le = addr;
__le64 *w_le = words_le + (b >> ENTRIES_SHIFT);
@ -170,7 +170,7 @@ static int sm_find_free(void *addr, unsigned begin, unsigned end,
{
while (begin < end) {
if (!(begin & (ENTRIES_PER_WORD - 1)) &&
bitmap_word_used(addr, begin)) {
dm_bitmap_word_used(addr, begin)) {
begin += ENTRIES_PER_WORD;
continue;
}

View File

@ -385,10 +385,10 @@ static void close_write(struct r1bio *r1_bio)
r1_bio->behind_master_bio = NULL;
}
/* clear the bitmap if all writes complete successfully */
bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
r1_bio->sectors,
!test_bit(R1BIO_Degraded, &r1_bio->state),
test_bit(R1BIO_BehindIO, &r1_bio->state));
md_bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
r1_bio->sectors,
!test_bit(R1BIO_Degraded, &r1_bio->state),
test_bit(R1BIO_BehindIO, &r1_bio->state));
md_write_end(r1_bio->mddev);
}
@ -781,7 +781,7 @@ static int raid1_congested(struct mddev *mddev, int bits)
static void flush_bio_list(struct r1conf *conf, struct bio *bio)
{
/* flush any pending bitmap writes to disk before proceeding w/ I/O */
bitmap_unplug(conf->mddev->bitmap);
md_bitmap_unplug(conf->mddev->bitmap);
wake_up(&conf->wait_barrier);
while (bio) { /* submit pending writes */
@ -1470,10 +1470,8 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
alloc_behind_master_bio(r1_bio, bio);
}
bitmap_startwrite(bitmap, r1_bio->sector,
r1_bio->sectors,
test_bit(R1BIO_BehindIO,
&r1_bio->state));
md_bitmap_startwrite(bitmap, r1_bio->sector, r1_bio->sectors,
test_bit(R1BIO_BehindIO, &r1_bio->state));
first_clone = 0;
}
@ -1880,8 +1878,7 @@ static void end_sync_write(struct bio *bio)
long sectors_to_go = r1_bio->sectors;
/* make sure these bits doesn't get cleared. */
do {
bitmap_end_sync(mddev->bitmap, s,
&sync_blocks, 1);
md_bitmap_end_sync(mddev->bitmap, s, &sync_blocks, 1);
s += sync_blocks;
sectors_to_go -= sync_blocks;
} while (sectors_to_go > 0);
@ -2626,12 +2623,12 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
* We can find the current addess in mddev->curr_resync
*/
if (mddev->curr_resync < max_sector) /* aborted */
bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
&sync_blocks, 1);
md_bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
&sync_blocks, 1);
else /* completed sync */
conf->fullsync = 0;
bitmap_close_sync(mddev->bitmap);
md_bitmap_close_sync(mddev->bitmap);
close_sync(conf);
if (mddev_is_clustered(mddev)) {
@ -2651,7 +2648,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
/* before building a request, check if we can skip these blocks..
* This call the bitmap_start_sync doesn't actually record anything
*/
if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
if (!md_bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
!conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
/* We can skip this block, and probably several more */
*skipped = 1;
@ -2669,7 +2666,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
* sector_nr + two times RESYNC_SECTORS
*/
bitmap_cond_end_sync(mddev->bitmap, sector_nr,
md_bitmap_cond_end_sync(mddev->bitmap, sector_nr,
mddev_is_clustered(mddev) && (sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high));
@ -2828,8 +2825,8 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
if (len == 0)
break;
if (sync_blocks == 0) {
if (!bitmap_start_sync(mddev->bitmap, sector_nr,
&sync_blocks, still_degraded) &&
if (!md_bitmap_start_sync(mddev->bitmap, sector_nr,
&sync_blocks, still_degraded) &&
!conf->fullsync &&
!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
break;
@ -3165,7 +3162,7 @@ static int raid1_resize(struct mddev *mddev, sector_t sectors)
mddev->array_sectors > newsize)
return -EINVAL;
if (mddev->bitmap) {
int ret = bitmap_resize(mddev->bitmap, newsize, 0, 0);
int ret = md_bitmap_resize(mddev->bitmap, newsize, 0, 0);
if (ret)
return ret;
}

View File

@ -440,10 +440,10 @@ static void raid10_end_read_request(struct bio *bio)
static void close_write(struct r10bio *r10_bio)
{
/* clear the bitmap if all writes complete successfully */
bitmap_endwrite(r10_bio->mddev->bitmap, r10_bio->sector,
r10_bio->sectors,
!test_bit(R10BIO_Degraded, &r10_bio->state),
0);
md_bitmap_endwrite(r10_bio->mddev->bitmap, r10_bio->sector,
r10_bio->sectors,
!test_bit(R10BIO_Degraded, &r10_bio->state),
0);
md_write_end(r10_bio->mddev);
}
@ -917,7 +917,7 @@ static void flush_pending_writes(struct r10conf *conf)
blk_start_plug(&plug);
/* flush any pending bitmap writes to disk
* before proceeding w/ I/O */
bitmap_unplug(conf->mddev->bitmap);
md_bitmap_unplug(conf->mddev->bitmap);
wake_up(&conf->wait_barrier);
while (bio) { /* submit pending writes */
@ -1102,7 +1102,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
/* we aren't scheduling, so we can do the write-out directly. */
bio = bio_list_get(&plug->pending);
bitmap_unplug(mddev->bitmap);
md_bitmap_unplug(mddev->bitmap);
wake_up(&conf->wait_barrier);
while (bio) { /* submit pending writes */
@ -1519,7 +1519,7 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
}
atomic_set(&r10_bio->remaining, 1);
bitmap_startwrite(mddev->bitmap, r10_bio->sector, r10_bio->sectors, 0);
md_bitmap_startwrite(mddev->bitmap, r10_bio->sector, r10_bio->sectors, 0);
for (i = 0; i < conf->copies; i++) {
if (r10_bio->devs[i].bio)
@ -2991,13 +2991,13 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
if (mddev->curr_resync < max_sector) { /* aborted */
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
&sync_blocks, 1);
md_bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
&sync_blocks, 1);
else for (i = 0; i < conf->geo.raid_disks; i++) {
sector_t sect =
raid10_find_virt(conf, mddev->curr_resync, i);
bitmap_end_sync(mddev->bitmap, sect,
&sync_blocks, 1);
md_bitmap_end_sync(mddev->bitmap, sect,
&sync_blocks, 1);
}
} else {
/* completed sync */
@ -3018,7 +3018,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
}
conf->fullsync = 0;
}
bitmap_close_sync(mddev->bitmap);
md_bitmap_close_sync(mddev->bitmap);
close_sync(conf);
*skipped = 1;
return sectors_skipped;
@ -3112,8 +3112,8 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
* we only need to recover the block if it is set in
* the bitmap
*/
must_sync = bitmap_start_sync(mddev->bitmap, sect,
&sync_blocks, 1);
must_sync = md_bitmap_start_sync(mddev->bitmap, sect,
&sync_blocks, 1);
if (sync_blocks < max_sync)
max_sync = sync_blocks;
if (!must_sync &&
@ -3158,8 +3158,8 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
}
}
must_sync = bitmap_start_sync(mddev->bitmap, sect,
&sync_blocks, still_degraded);
must_sync = md_bitmap_start_sync(mddev->bitmap, sect,
&sync_blocks, still_degraded);
any_working = 0;
for (j=0; j<conf->copies;j++) {
@ -3335,13 +3335,12 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
* safety reason, which ensures curr_resync_completed is
* updated in bitmap_cond_end_sync.
*/
bitmap_cond_end_sync(mddev->bitmap, sector_nr,
mddev_is_clustered(mddev) &&
(sector_nr + 2 * RESYNC_SECTORS >
conf->cluster_sync_high));
md_bitmap_cond_end_sync(mddev->bitmap, sector_nr,
mddev_is_clustered(mddev) &&
(sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high));
if (!bitmap_start_sync(mddev->bitmap, sector_nr,
&sync_blocks, mddev->degraded) &&
if (!md_bitmap_start_sync(mddev->bitmap, sector_nr,
&sync_blocks, mddev->degraded) &&
!conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED,
&mddev->recovery)) {
/* We can skip this block */
@ -4022,7 +4021,7 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors)
mddev->array_sectors > size)
return -EINVAL;
if (mddev->bitmap) {
int ret = bitmap_resize(mddev->bitmap, size, 0, 0);
int ret = md_bitmap_resize(mddev->bitmap, size, 0, 0);
if (ret)
return ret;
}
@ -4287,10 +4286,9 @@ static int raid10_start_reshape(struct mddev *mddev)
spin_unlock_irq(&conf->device_lock);
if (mddev->delta_disks && mddev->bitmap) {
ret = bitmap_resize(mddev->bitmap,
raid10_size(mddev, 0,
conf->geo.raid_disks),
0, 0);
ret = md_bitmap_resize(mddev->bitmap,
raid10_size(mddev, 0, conf->geo.raid_disks),
0, 0);
if (ret)
goto abort;
}

View File

@ -324,10 +324,10 @@ void r5c_handle_cached_data_endio(struct r5conf *conf,
if (sh->dev[i].written) {
set_bit(R5_UPTODATE, &sh->dev[i].flags);
r5c_return_dev_pending_writes(conf, &sh->dev[i]);
bitmap_endwrite(conf->mddev->bitmap, sh->sector,
STRIPE_SECTORS,
!test_bit(STRIPE_DEGRADED, &sh->state),
0);
md_bitmap_endwrite(conf->mddev->bitmap, sh->sector,
STRIPE_SECTORS,
!test_bit(STRIPE_DEGRADED, &sh->state),
0);
}
}
}

View File

@ -3299,8 +3299,8 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx,
*/
set_bit(STRIPE_BITMAP_PENDING, &sh->state);
spin_unlock_irq(&sh->stripe_lock);
bitmap_startwrite(conf->mddev->bitmap, sh->sector,
STRIPE_SECTORS, 0);
md_bitmap_startwrite(conf->mddev->bitmap, sh->sector,
STRIPE_SECTORS, 0);
spin_lock_irq(&sh->stripe_lock);
clear_bit(STRIPE_BITMAP_PENDING, &sh->state);
if (!sh->batch_head) {
@ -3390,8 +3390,8 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
bi = nextbi;
}
if (bitmap_end)
bitmap_endwrite(conf->mddev->bitmap, sh->sector,
STRIPE_SECTORS, 0, 0);
md_bitmap_endwrite(conf->mddev->bitmap, sh->sector,
STRIPE_SECTORS, 0, 0);
bitmap_end = 0;
/* and fail all 'written' */
bi = sh->dev[i].written;
@ -3436,8 +3436,8 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
}
}
if (bitmap_end)
bitmap_endwrite(conf->mddev->bitmap, sh->sector,
STRIPE_SECTORS, 0, 0);
md_bitmap_endwrite(conf->mddev->bitmap, sh->sector,
STRIPE_SECTORS, 0, 0);
/* If we were in the middle of a write the parity block might
* still be locked - so just clear all R5_LOCKED flags
*/
@ -3777,10 +3777,10 @@ static void handle_stripe_clean_event(struct r5conf *conf,
bio_endio(wbi);
wbi = wbi2;
}
bitmap_endwrite(conf->mddev->bitmap, sh->sector,
STRIPE_SECTORS,
!test_bit(STRIPE_DEGRADED, &sh->state),
0);
md_bitmap_endwrite(conf->mddev->bitmap, sh->sector,
STRIPE_SECTORS,
!test_bit(STRIPE_DEGRADED, &sh->state),
0);
if (head_sh->batch_head) {
sh = list_first_entry(&sh->batch_list,
struct stripe_head,
@ -5543,10 +5543,10 @@ static void make_discard_request(struct mddev *mddev, struct bio *bi)
for (d = 0;
d < conf->raid_disks - conf->max_degraded;
d++)
bitmap_startwrite(mddev->bitmap,
sh->sector,
STRIPE_SECTORS,
0);
md_bitmap_startwrite(mddev->bitmap,
sh->sector,
STRIPE_SECTORS,
0);
sh->bm_seq = conf->seq_flush + 1;
set_bit(STRIPE_BIT_DELAY, &sh->state);
}
@ -6024,11 +6024,11 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n
}
if (mddev->curr_resync < max_sector) /* aborted */
bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
&sync_blocks, 1);
md_bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
&sync_blocks, 1);
else /* completed sync */
conf->fullsync = 0;
bitmap_close_sync(mddev->bitmap);
md_bitmap_close_sync(mddev->bitmap);
return 0;
}
@ -6057,7 +6057,7 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n
}
if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) &&
!conf->fullsync &&
!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
!md_bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
sync_blocks >= STRIPE_SECTORS) {
/* we can skip this block, and probably more */
sync_blocks /= STRIPE_SECTORS;
@ -6065,7 +6065,7 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n
return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */
}
bitmap_cond_end_sync(mddev->bitmap, sector_nr, false);
md_bitmap_cond_end_sync(mddev->bitmap, sector_nr, false);
sh = raid5_get_active_stripe(conf, sector_nr, 0, 1, 0);
if (sh == NULL) {
@ -6088,7 +6088,7 @@ static inline sector_t raid5_sync_request(struct mddev *mddev, sector_t sector_n
}
rcu_read_unlock();
bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, still_degraded);
md_bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, still_degraded);
set_bit(STRIPE_SYNC_REQUESTED, &sh->state);
set_bit(STRIPE_HANDLE, &sh->state);
@ -6289,7 +6289,7 @@ static void raid5d(struct md_thread *thread)
/* Now is a good time to flush some bitmap updates */
conf->seq_flush++;
spin_unlock_irq(&conf->device_lock);
bitmap_unplug(mddev->bitmap);
md_bitmap_unplug(mddev->bitmap);
spin_lock_irq(&conf->device_lock);
conf->seq_write = conf->seq_flush;
activate_bit_delay(conf, conf->temp_inactive_list);
@ -7745,7 +7745,7 @@ static int raid5_resize(struct mddev *mddev, sector_t sectors)
mddev->array_sectors > newsize)
return -EINVAL;
if (mddev->bitmap) {
int ret = bitmap_resize(mddev->bitmap, sectors, 0, 0);
int ret = md_bitmap_resize(mddev->bitmap, sectors, 0, 0);
if (ret)
return ret;
}

View File

@ -104,6 +104,14 @@
* contain all bit positions from 0 to 'bits' - 1.
*/
/*
* Allocation and deallocation of bitmap.
* Provided in lib/bitmap.c to avoid circular dependency.
*/
extern unsigned long *bitmap_alloc(unsigned int nbits, gfp_t flags);
extern unsigned long *bitmap_zalloc(unsigned int nbits, gfp_t flags);
extern void bitmap_free(const unsigned long *bitmap);
/*
* lib/bitmap.c provides these functions:
*/

View File

@ -2,6 +2,8 @@
#ifndef _GPIO_KEYS_H
#define _GPIO_KEYS_H
#include <linux/types.h>
struct device;
/**

View File

@ -17,10 +17,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
*/
#ifndef _LINUX_JOYSTICK_H
#define _LINUX_JOYSTICK_H

View File

@ -18,10 +18,6 @@
* 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
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
*/
#ifndef _UAPI_LINUX_JOYSTICK_H
#define _UAPI_LINUX_JOYSTICK_H

View File

@ -189,6 +189,13 @@
*
*----------------------------- Connector settings ----------------------------
*
* unique-id
* Values: <string>
*
* After device instance initialization each connector is assigned a
* unique ID, so it can be identified by the backend by this ID.
* This can be UUID or such.
*
* resolution
* Values: <width, uint32_t>x<height, uint32_t>
*
@ -368,6 +375,7 @@
#define XENDISPL_FIELD_EVT_CHANNEL "evt-event-channel"
#define XENDISPL_FIELD_RESOLUTION "resolution"
#define XENDISPL_FIELD_BE_ALLOC "be-alloc"
#define XENDISPL_FIELD_UNIQUE_ID "unique-id"
/*
******************************************************************************

View File

@ -51,6 +51,18 @@
* corresponding entries in XenStore and puts 1 as the value of the entry.
* If a feature is not supported then 0 must be set or feature entry omitted.
*
* feature-disable-keyboard
* Values: <uint>
*
* If there is no need to expose a virtual keyboard device by the
* frontend then this must be set to 1.
*
* feature-disable-pointer
* Values: <uint>
*
* If there is no need to expose a virtual pointer device by the
* frontend then this must be set to 1.
*
* feature-abs-pointer
* Values: <uint>
*
@ -63,6 +75,22 @@
* Backends, which support reporting of multi-touch events
* should set this to 1.
*
* feature-raw-pointer
* Values: <uint>
*
* Backends, which support reporting raw (unscaled) absolute coordinates
* for pointer devices should set this to 1. Raw (unscaled) values have
* a range of [0, 0x7fff].
*
*----------------------- Device Instance Parameters ------------------------
*
* unique-id
* Values: <string>
*
* After device instance initialization it is assigned a unique ID,
* so every instance of the frontend can be identified by the backend
* by this ID. This can be UUID or such.
*
*------------------------- Pointer Device Parameters ------------------------
*
* width
@ -77,6 +105,25 @@
* Maximum Y coordinate (height) to be used by the frontend
* while reporting input events, pixels, [0; UINT32_MAX].
*
*----------------------- Multi-touch Device Parameters ----------------------
*
* multi-touch-num-contacts
* Values: <uint>
*
* Number of simultaneous touches reported.
*
* multi-touch-width
* Values: <uint>
*
* Width of the touch area to be used by the frontend
* while reporting input events, pixels, [0; UINT32_MAX].
*
* multi-touch-height
* Values: <uint>
*
* Height of the touch area to be used by the frontend
* while reporting input events, pixels, [0; UINT32_MAX].
*
*****************************************************************************
* Frontend XenBus Nodes
*****************************************************************************
@ -98,6 +145,13 @@
*
* Request backend to report multi-touch events.
*
* request-raw-pointer
* Values: <uint>
*
* Request backend to report raw unscaled absolute pointer coordinates.
* This option is only valid if request-abs-pointer is also set.
* Raw unscaled coordinates have the range [0, 0x7fff]
*
*----------------------- Request Transport Parameters -----------------------
*
* event-channel
@ -117,25 +171,6 @@
*
* OBSOLETE, not recommended for use.
* PFN of the shared page.
*
*----------------------- Multi-touch Device Parameters -----------------------
*
* multi-touch-num-contacts
* Values: <uint>
*
* Number of simultaneous touches reported.
*
* multi-touch-width
* Values: <uint>
*
* Width of the touch area to be used by the frontend
* while reporting input events, pixels, [0; UINT32_MAX].
*
* multi-touch-height
* Values: <uint>
*
* Height of the touch area to be used by the frontend
* while reporting input events, pixels, [0; UINT32_MAX].
*/
/*
@ -163,9 +198,13 @@
#define XENKBD_DRIVER_NAME "vkbd"
#define XENKBD_FIELD_FEAT_DSBL_KEYBRD "feature-disable-keyboard"
#define XENKBD_FIELD_FEAT_DSBL_POINTER "feature-disable-pointer"
#define XENKBD_FIELD_FEAT_ABS_POINTER "feature-abs-pointer"
#define XENKBD_FIELD_FEAT_RAW_POINTER "feature-raw-pointer"
#define XENKBD_FIELD_FEAT_MTOUCH "feature-multi-touch"
#define XENKBD_FIELD_REQ_ABS_POINTER "request-abs-pointer"
#define XENKBD_FIELD_REQ_RAW_POINTER "request-raw-pointer"
#define XENKBD_FIELD_REQ_MTOUCH "request-multi-touch"
#define XENKBD_FIELD_RING_GREF "page-gref"
#define XENKBD_FIELD_EVT_CHANNEL "event-channel"
@ -174,6 +213,7 @@
#define XENKBD_FIELD_MT_WIDTH "multi-touch-width"
#define XENKBD_FIELD_MT_HEIGHT "multi-touch-height"
#define XENKBD_FIELD_MT_NUM_CONTACTS "multi-touch-num-contacts"
#define XENKBD_FIELD_UNIQUE_ID "unique-id"
/* OBSOLETE, not recommended for use */
#define XENKBD_FIELD_RING_REF "page-ref"

View File

@ -278,13 +278,11 @@
* defined under the same device.
*
* unique-id
* Values: <uint32_t>
* Values: <string>
*
* After stream initialization it is assigned a unique ID (within the front
* driver), so every stream of the frontend can be identified by the
* backend by this ID. This is not equal to stream-idx as the later is
* zero based within the device, but this index is contigous within the
* driver.
* After stream initialization it is assigned a unique ID, so every
* stream of the frontend can be identified by the backend by this ID.
* This can be UUID or such.
*
*-------------------- Stream Request Transport Parameters --------------------
*

View File

@ -13,6 +13,7 @@
#include <linux/bitops.h>
#include <linux/bug.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/uaccess.h>
@ -1125,6 +1126,25 @@ void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int n
EXPORT_SYMBOL(bitmap_copy_le);
#endif
unsigned long *bitmap_alloc(unsigned int nbits, gfp_t flags)
{
return kmalloc_array(BITS_TO_LONGS(nbits), sizeof(unsigned long),
flags);
}
EXPORT_SYMBOL(bitmap_alloc);
unsigned long *bitmap_zalloc(unsigned int nbits, gfp_t flags)
{
return bitmap_alloc(nbits, flags | __GFP_ZERO);
}
EXPORT_SYMBOL(bitmap_zalloc);
void bitmap_free(const unsigned long *bitmap)
{
kfree(bitmap);
}
EXPORT_SYMBOL(bitmap_free);
#if BITS_PER_LONG == 64
/**
* bitmap_from_arr32 - copy the contents of u32 array of bits to bitmap