Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bbe963f1 authored by Andres Salomon's avatar Andres Salomon Committed by Greg Kroah-Hartman
Browse files

staging: olpc_dcon: move more variables into dcon_priv



This moves dcon_source and dcon_pending into the dcon_priv struct.

Because these variables are used by the IRQ handler (which is
registered in the model-specific callbacks), we end up needing
to move dcon_priv into olpc_dcon.h.  This also changes the IRQ
registration to use the dcon_priv pointer as dev_id, instead of
dcon_driver.

Signed-off-by: default avatarAndres Salomon <dilinger@queued.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 097cd83a
Loading
Loading
Loading
Loading
+14 −37
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@
#include <linux/delay.h>
#include <linux/backlight.h>
#include <linux/device.h>
#include <linux/notifier.h>
#include <linux/uaccess.h>
#include <linux/ctype.h>
#include <linux/reboot.h>
@@ -46,24 +45,6 @@ module_param(useaa, int, 0444);

static struct dcon_platform_data *pdata;

struct dcon_priv {
	struct i2c_client *client;
	struct fb_info *fbinfo;

	struct work_struct switch_source;
	struct notifier_block reboot_nb;
	struct notifier_block fbevent_nb;

	/* Shadow register for the DCON_REG_MODE register */
	u8 disp_mode;

	/* Current output type; true == mono, false == color */
	bool mono;
	bool asleep;
	/* This get set while controlling fb blank state from the driver */
	bool ignore_fb_events;
};

/* I2C structures */

/* Platform devices */
@@ -72,12 +53,6 @@ static struct platform_device *dcon_device;
/* Backlight device */
static struct backlight_device *dcon_bl_dev;

/* Current source, initialized at probe time */
int dcon_source;

/* Desired source */
int dcon_pending;

/* Variables used during switches */
static int dcon_switched;
static struct timespec dcon_irq_time;
@@ -119,7 +94,7 @@ static int dcon_hw_init(struct dcon_priv *dcon, int is_init)
	if (is_init) {
		printk(KERN_INFO "olpc-dcon:  Discovered DCON version %x\n",
				ver & 0xFF);
		rc = pdata->init();
		rc = pdata->init(dcon);
		if (rc != 0) {
			printk(KERN_ERR "olpc-dcon:  Unable to init.\n");
			goto err;
@@ -366,9 +341,9 @@ static void dcon_source_switch(struct work_struct *work)
	struct dcon_priv *dcon = container_of(work, struct dcon_priv,
			switch_source);
	DECLARE_WAITQUEUE(wait, current);
	int source = dcon_pending;
	int source = dcon->pending_src;

	if (dcon_source == source)
	if (dcon->curr_src == source)
		return;

	dcon_load_holdoff();
@@ -406,7 +381,7 @@ static void dcon_source_switch(struct work_struct *work)
		 */
		if (!dcon_blank_fb(dcon, false)) {
			printk(KERN_ERR "olpc-dcon:  Failed to enter CPU mode\n");
			dcon_pending = DCON_SOURCE_DCON;
			dcon->pending_src = DCON_SOURCE_DCON;
			return;
		}

@@ -468,17 +443,17 @@ static void dcon_source_switch(struct work_struct *work)
		BUG();
	}

	dcon_source = source;
	dcon->curr_src = source;
}

static void dcon_set_source(struct dcon_priv *dcon, int arg)
{
	if (dcon_pending == arg)
	if (dcon->pending_src == arg)
		return;

	dcon_pending = arg;
	dcon->pending_src = arg;

	if ((dcon_source != arg) && !work_pending(&dcon->switch_source))
	if ((dcon->curr_src != arg) && !work_pending(&dcon->switch_source))
		schedule_work(&dcon->switch_source);
}

@@ -524,7 +499,8 @@ static ssize_t dcon_sleep_show(struct device *dev,
static ssize_t dcon_freeze_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n", dcon_source == DCON_SOURCE_DCON ? 1 : 0);
	struct dcon_priv *dcon = dev_get_drvdata(dev);
	return sprintf(buf, "%d\n", dcon->curr_src == DCON_SOURCE_DCON ? 1 : 0);
}

static ssize_t dcon_mono_show(struct device *dev,
@@ -765,7 +741,7 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id)
	platform_device_unregister(dcon_device);
	dcon_device = NULL;
 eirq:
	free_irq(DCON_IRQ, &dcon_driver);
	free_irq(DCON_IRQ, dcon);
 einit:
	i2c_set_clientdata(client, NULL);
	kfree(dcon);
@@ -782,7 +758,7 @@ static int dcon_remove(struct i2c_client *client)
	unregister_reboot_notifier(&dcon->reboot_nb);
	atomic_notifier_chain_unregister(&panic_notifier_list, &dcon_panic_nb);

	free_irq(DCON_IRQ, &dcon_driver);
	free_irq(DCON_IRQ, dcon);

	if (dcon_bl_dev != NULL)
		backlight_device_unregister(dcon_bl_dev);
@@ -826,6 +802,7 @@ static int dcon_resume(struct i2c_client *client)

irqreturn_t dcon_interrupt(int irq, void *id)
{
	struct dcon_priv *dcon = id;
	int status = pdata->read_status();

	if (status == -1)
@@ -851,7 +828,7 @@ irqreturn_t dcon_interrupt(int irq, void *id)
		 * of the DCON happened long before this point.
		 * see http://dev.laptop.org/ticket/9869
		 */
		if (dcon_source != dcon_pending && !dcon_switched) {
		if (dcon->curr_src != dcon->pending_src && !dcon_switched) {
			dcon_switched = 1;
			getnstimeofday(&dcon_irq_time);
			wake_up(&dcon_wait_queue);
+28 −4
Original line number Diff line number Diff line
#ifndef OLPC_DCON_H_
#define OLPC_DCON_H_

#include <linux/notifier.h>
#include <linux/workqueue.h>

/* DCON registers */

#define DCON_REG_ID		 0
@@ -44,8 +47,32 @@
/* Interrupt */
#define DCON_IRQ                6

struct dcon_priv {
	struct i2c_client *client;
	struct fb_info *fbinfo;

	struct work_struct switch_source;
	struct notifier_block reboot_nb;
	struct notifier_block fbevent_nb;

	/* Shadow register for the DCON_REG_MODE register */
	u8 disp_mode;

	/* Current source, initialized at probe time */
	int curr_src;

	/* Desired source */
	int pending_src;

	/* Current output type; true == mono, false == color */
	bool mono;
	bool asleep;
	/* This get set while controlling fb blank state from the driver */
	bool ignore_fb_events;
};

struct dcon_platform_data {
	int (*init)(void);
	int (*init)(struct dcon_priv *);
	void (*bus_stabilize_wiggle)(void);
	void (*set_dconload)(int);
	u8 (*read_status)(void);
@@ -53,10 +80,7 @@ struct dcon_platform_data {

#include <linux/interrupt.h>

extern int dcon_source;
extern int dcon_pending;
extern irqreturn_t dcon_interrupt(int irq, void *id);
extern struct i2c_driver dcon_driver;

#ifdef CONFIG_FB_OLPC_DCON_1
extern struct dcon_platform_data dcon_pdata_xo_1;
+5 −5
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

#include "olpc_dcon.h"

static int dcon_init_xo_1(void)
static int dcon_init_xo_1(struct dcon_priv *dcon)
{
	unsigned char lob;

@@ -54,10 +54,10 @@ static int dcon_init_xo_1(void)
	 * then a value is set.  So, future readings of the pin can use
	 * READ_BACK, but the first one cannot.  Awesome, huh?
	 */
	dcon_source = cs5535_gpio_isset(OLPC_GPIO_DCON_LOAD, GPIO_OUTPUT_VAL)
	dcon->curr_src = cs5535_gpio_isset(OLPC_GPIO_DCON_LOAD, GPIO_OUTPUT_VAL)
		? DCON_SOURCE_CPU
		: DCON_SOURCE_DCON;
	dcon_pending = dcon_source;
	dcon->pending_src = dcon->curr_src;

	/* Set the directions for the GPIO pins */
	gpio_direction_input(OLPC_GPIO_DCON_STAT0);
@@ -65,7 +65,7 @@ static int dcon_init_xo_1(void)
	gpio_direction_input(OLPC_GPIO_DCON_IRQ);
	gpio_direction_input(OLPC_GPIO_DCON_BLANK);
	gpio_direction_output(OLPC_GPIO_DCON_LOAD,
			dcon_source == DCON_SOURCE_CPU);
			dcon->curr_src == DCON_SOURCE_CPU);

	/* Set up the interrupt mappings */

@@ -81,7 +81,7 @@ static int dcon_init_xo_1(void)
	outb(lob, 0x4d0);

	/* Register the interupt handler */
	if (request_irq(DCON_IRQ, &dcon_interrupt, 0, "DCON", &dcon_driver)) {
	if (request_irq(DCON_IRQ, &dcon_interrupt, 0, "DCON", dcon)) {
		printk(KERN_ERR "olpc-dcon: failed to request DCON's irq\n");
		goto err_req_irq;
	}
+4 −5
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ static int dcon_was_irq(void)
	return 0;
}

static int dcon_init_xo_1_5(void)
static int dcon_init_xo_1_5(struct dcon_priv *dcon)
{
	unsigned int irq;
	u_int8_t tmp;
@@ -96,20 +96,19 @@ static int dcon_init_xo_1_5(void)

	/* Determine the current state of DCONLOAD, likely set by firmware */
	/* GPIO1 */
	dcon_source = (inl(VX855_GENL_PURPOSE_OUTPUT) & 0x1000) ?
	dcon->curr_src = (inl(VX855_GENL_PURPOSE_OUTPUT) & 0x1000) ?
			DCON_SOURCE_CPU : DCON_SOURCE_DCON;
	dcon_pending = dcon_source;
	dcon->pending_src = dcon->curr_src;

	pci_dev_put(pdev);

	/* we're sharing the IRQ with ACPI */
	irq = acpi_gbl_FADT.sci_interrupt;
	if (request_irq(irq, &dcon_interrupt, IRQF_SHARED, "DCON", &dcon_driver)) {
	if (request_irq(irq, &dcon_interrupt, IRQF_SHARED, "DCON", dcon)) {
		printk(KERN_ERR PREFIX "DCON (IRQ%d) allocation failed\n", irq);
		return 1;
	}


	return 0;
}