~mil/ppbbq10

6e91b2b2928d9eb9cd3cbf793c24a61e858a9319 — Miles Alan 9 months ago cafdd2d
Use polling instead of interrupt to process events in ppbbq10_irq_handler

Make failure to acquire IRQ non-fatal
1 files changed, 25 insertions(+), 5 deletions(-)

M ppbbq10.c
M ppbbq10.c => ppbbq10.c +25 -5
@@ 1,9 1,11 @@
#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>


@@ 52,18 54,21 @@ struct ppbbq10_data {
	struct input_dev *input;
};


/* function declarations */
static int ppbbq10_backlight_update_status(struct backlight_device *bd);
static void __exit ppbbq10_exit(void);
static int __init ppbbq10_init(void);
static irqreturn_t ppbbq10_irq_handler(int irq, void *dev_id);
static int ppbbq10_probe(struct i2c_client *client, const struct i2c_device_id *id);
static int ppbbq10_poll_kthread(void *data);
static int ppbbq10_probe(struct i2c_client *client);
static void ppbbq10_read_fifo(struct ppbbq10_data *drv_data);
static int ppbbq10_read_reg(struct ppbbq10_data *drv_data, u8 reg, u8 *buf, u8 len);
static void ppbbq10_update_locks(struct ppbbq10_data *drv_data);
static int ppbbq10_write_data(struct ppbbq10_data *drv_data, u8 reg, const u8 *buf, u8 len);
static int ppbbq10_write_reg(struct ppbbq10_data *drv_data, u8 reg);


/* variables */
static unsigned short keymap_norm[NUM_KEYCODES] = {
	[0x01] = KEY_UP,


@@ 123,6 128,9 @@ static struct backlight_properties backlight_props = {
	.max_brightness = 255,
	.brightness		= 127,
};
static struct task_struct *ppbbq10_kthread;
struct ppbbq10_data *drv_data;


/* function implementations */
static int


@@ 140,6 148,8 @@ ppbbq10_exit(void)
{
	printk(KERN_INFO "Unregister ppbbq10 kernel module.\n");
	i2c_unregister_device(client);
	kthread_stop(ppbbq10_kthread);

	/*i2c_del_driver(&ppbbq10_driver);*/
}



@@ 154,13 164,15 @@ ppbbq10_init(void)
	}
	client = i2c_new_client_device(adapter, ppbbq10_i2c_board_info);
	//client->irq = gpio_to_irq(2);
	ppbbq10_probe(client);
	ppbbq10_kthread = kthread_create(ppbbq10_poll_kthread, NULL, "ppbbq10_pollthread");
	wake_up_process(ppbbq10_kthread);
	return 0;
}

static irqreturn_t
ppbbq10_irq_handler(int irq, void *dev_id)
{
	struct ppbbq10_data *drv_data = dev_id;
	struct i2c_client *client = drv_data->client;
	int error;
	u8 reg;


@@ 197,11 209,19 @@ ppbbq10_irq_handler(int irq, void *dev_id)
	return IRQ_HANDLED;
}

static int ppbbq10_poll_kthread(void *data)
{
	while (!kthread_should_stop()) {
		usleep_range(1000 * 10, (1000 * 10) + 1); // 10ms poll
		ppbbq10_irq_handler(0, NULL);
	}
	return 0;
}

static int
ppbbq10_probe(struct i2c_client *client, const struct i2c_device_id *id)
ppbbq10_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct ppbbq10_data *drv_data;
	struct backlight_device *bd;
	struct input_dev *input;
	int error;


@@ 276,7 296,7 @@ ppbbq10_probe(struct i2c_client *client, const struct i2c_device_id *id)
										client->name, drv_data);
	if (error) {
		dev_err(dev, "Failed to claim irq %d; error %d\n", client->irq, error);
		return error;
		//return error;
	}

	error = input_register_device(input);