staging: panel: Remove unused variable
[deliverable/linux.git] / drivers / staging / panel / panel.c
index 6d1a32097d3cf30f33ad7e1be012e1532d71d15f..b68a9c3f2d0f486e0a44e8b1387e5910c6d8d98a 100644 (file)
 #define LCD_ESCAPE_LEN         24      /* max chars for LCD escape command */
 #define LCD_ESCAPE_CHAR        27      /* use char 27 for escape command */
 
+#define NOT_SET                        -1
+
 /* macros to simplify use of the parallel port */
 #define r_ctr(x)        (parport_read_control((x)->port))
 #define r_dtr(x)        (parport_read_data((x)->port))
@@ -210,6 +212,10 @@ static pmask_t phys_prev;
 static char inputs_stable;
 
 /* these variables are specific to the keypad */
+static struct {
+       bool enabled;
+} keypad;
+
 static char keypad_buffer[KEYPAD_BUFFER];
 static int keypad_buflen;
 static int keypad_start;
@@ -217,17 +223,47 @@ static char keypressed;
 static wait_queue_head_t keypad_read_wait;
 
 /* lcd-specific variables */
-
-/* contains the LCD config state */
-static unsigned long int lcd_flags;
-/* contains the LCD X offset */
-static unsigned long int lcd_addr_x;
-/* contains the LCD Y offset */
-static unsigned long int lcd_addr_y;
-/* current escape sequence, 0 terminated */
-static char lcd_escape[LCD_ESCAPE_LEN + 1];
-/* not in escape state. >=0 = escape cmd len */
-static int lcd_escape_len = -1;
+static struct {
+       bool enabled;
+       bool initialized;
+       bool must_clear;
+
+       int height;
+       int width;
+       int bwidth;
+       int hwidth;
+       int charset;
+       int proto;
+       int light_tempo;
+
+       /* TODO: use union here? */
+       struct {
+               int e;
+               int rs;
+               int rw;
+               int cl;
+               int da;
+               int bl;
+       } pins;
+
+       /* contains the LCD config state */
+       unsigned long int flags;
+
+       /* Contains the LCD X and Y offset */
+       struct {
+               unsigned long int x;
+               unsigned long int y;
+       } addr;
+
+       /* Current escape sequence and it's length or -1 if outside */
+       struct {
+               char buf[LCD_ESCAPE_LEN + 1];
+               int len;
+       } esc_seq;
+} lcd;
+
+/* Needed only for init */
+static int selected_lcd_type = NOT_SET;
 
 /*
  * Bit masks to convert LCD signals to parallel port outputs.
@@ -302,14 +338,15 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES];
 /*
  * Construct custom config from the kernel's configuration
  */
-#define DEFAULT_PROFILE         PANEL_PROFILE_LARGE
 #define DEFAULT_PARPORT         0
-#define DEFAULT_LCD             LCD_TYPE_OLD
-#define DEFAULT_KEYPAD          KEYPAD_TYPE_OLD
+#define DEFAULT_PROFILE         PANEL_PROFILE_LARGE
+#define DEFAULT_KEYPAD_TYPE     KEYPAD_TYPE_OLD
+#define DEFAULT_LCD_TYPE        LCD_TYPE_OLD
+#define DEFAULT_LCD_HEIGHT      2
 #define DEFAULT_LCD_WIDTH       40
 #define DEFAULT_LCD_BWIDTH      40
 #define DEFAULT_LCD_HWIDTH      64
-#define DEFAULT_LCD_HEIGHT      2
+#define DEFAULT_LCD_CHARSET     LCD_CHARSET_NORMAL
 #define DEFAULT_LCD_PROTO       LCD_PROTO_PARALLEL
 
 #define DEFAULT_LCD_PIN_E       PIN_AUTOLF
@@ -318,27 +355,31 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES];
 #define DEFAULT_LCD_PIN_SCL     PIN_STROBE
 #define DEFAULT_LCD_PIN_SDA     PIN_D0
 #define DEFAULT_LCD_PIN_BL      PIN_NOT_SET
-#define DEFAULT_LCD_CHARSET     LCD_CHARSET_NORMAL
-
-#ifdef CONFIG_PANEL_PROFILE
-#undef DEFAULT_PROFILE
-#define DEFAULT_PROFILE CONFIG_PANEL_PROFILE
-#endif
 
 #ifdef CONFIG_PANEL_PARPORT
 #undef DEFAULT_PARPORT
 #define DEFAULT_PARPORT CONFIG_PANEL_PARPORT
 #endif
 
+#ifdef CONFIG_PANEL_PROFILE
+#undef DEFAULT_PROFILE
+#define DEFAULT_PROFILE CONFIG_PANEL_PROFILE
+#endif
+
 #if DEFAULT_PROFILE == 0       /* custom */
 #ifdef CONFIG_PANEL_KEYPAD
-#undef DEFAULT_KEYPAD
-#define DEFAULT_KEYPAD CONFIG_PANEL_KEYPAD
+#undef DEFAULT_KEYPAD_TYPE
+#define DEFAULT_KEYPAD_TYPE CONFIG_PANEL_KEYPAD
 #endif
 
 #ifdef CONFIG_PANEL_LCD
-#undef DEFAULT_LCD
-#define DEFAULT_LCD CONFIG_PANEL_LCD
+#undef DEFAULT_LCD_TYPE
+#define DEFAULT_LCD_TYPE CONFIG_PANEL_LCD
+#endif
+
+#ifdef CONFIG_PANEL_LCD_HEIGHT
+#undef DEFAULT_LCD_HEIGHT
+#define DEFAULT_LCD_HEIGHT CONFIG_PANEL_LCD_HEIGHT
 #endif
 
 #ifdef CONFIG_PANEL_LCD_WIDTH
@@ -356,9 +397,9 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES];
 #define DEFAULT_LCD_HWIDTH CONFIG_PANEL_LCD_HWIDTH
 #endif
 
-#ifdef CONFIG_PANEL_LCD_HEIGHT
-#undef DEFAULT_LCD_HEIGHT
-#define DEFAULT_LCD_HEIGHT CONFIG_PANEL_LCD_HEIGHT
+#ifdef CONFIG_PANEL_LCD_CHARSET
+#undef DEFAULT_LCD_CHARSET
+#define DEFAULT_LCD_CHARSET CONFIG_PANEL_LCD_CHARSET
 #endif
 
 #ifdef CONFIG_PANEL_LCD_PROTO
@@ -396,25 +437,18 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES];
 #define DEFAULT_LCD_PIN_BL CONFIG_PANEL_LCD_PIN_BL
 #endif
 
-#ifdef CONFIG_PANEL_LCD_CHARSET
-#undef DEFAULT_LCD_CHARSET
-#define DEFAULT_LCD_CHARSET CONFIG_PANEL_LCD_CHARSET
-#endif
-
 #endif /* DEFAULT_PROFILE == 0 */
 
 /* global variables */
-static int keypad_open_cnt;    /* #times opened */
-static int lcd_open_cnt;       /* #times opened */
+
+/* Device single-open policy control */
+static atomic_t lcd_available = ATOMIC_INIT(1);
+static atomic_t keypad_available = ATOMIC_INIT(1);
+
 static struct pardevice *pprt;
 
-static int lcd_initialized;
 static int keypad_initialized;
 
-static int light_tempo;
-
-static char lcd_must_clear;
-static char lcd_left_shift;
 static char init_in_progress;
 
 static void (*lcd_write_cmd)(int);
@@ -426,59 +460,51 @@ static struct timer_list scan_timer;
 
 MODULE_DESCRIPTION("Generic parallel port LCD/Keypad driver");
 
-static int parport = -1;
+static int parport = DEFAULT_PARPORT;
 module_param(parport, int, 0000);
 MODULE_PARM_DESC(parport, "Parallel port index (0=lpt1, 1=lpt2, ...)");
 
-static int lcd_height = -1;
+static int profile = DEFAULT_PROFILE;
+module_param(profile, int, 0000);
+MODULE_PARM_DESC(profile,
+                "1=16x2 old kp; 2=serial 16x2, new kp; 3=16x2 hantronix; "
+                "4=16x2 nexcom; default=40x2, old kp");
+
+static int keypad_type = NOT_SET;
+module_param(keypad_type, int, 0000);
+MODULE_PARM_DESC(keypad_type,
+                "Keypad type: 0=none, 1=old 6 keys, 2=new 6+1 keys, 3=nexcom 4 keys");
+
+static int lcd_type = NOT_SET;
+module_param(lcd_type, int, 0000);
+MODULE_PARM_DESC(lcd_type,
+                "LCD type: 0=none, 1=old //, 2=serial ks0074, 3=hantronix //, 4=nexcom //, 5=compiled-in");
+
+static int lcd_height = NOT_SET;
 module_param(lcd_height, int, 0000);
 MODULE_PARM_DESC(lcd_height, "Number of lines on the LCD");
 
-static int lcd_width = -1;
+static int lcd_width = NOT_SET;
 module_param(lcd_width, int, 0000);
 MODULE_PARM_DESC(lcd_width, "Number of columns on the LCD");
 
-static int lcd_bwidth = -1;    /* internal buffer width (usually 40) */
+static int lcd_bwidth = NOT_SET;       /* internal buffer width (usually 40) */
 module_param(lcd_bwidth, int, 0000);
 MODULE_PARM_DESC(lcd_bwidth, "Internal LCD line width (40)");
 
-static int lcd_hwidth = -1;    /* hardware buffer width (usually 64) */
+static int lcd_hwidth = NOT_SET;       /* hardware buffer width (usually 64) */
 module_param(lcd_hwidth, int, 0000);
 MODULE_PARM_DESC(lcd_hwidth, "LCD line hardware address (64)");
 
-static int lcd_enabled = -1;
-module_param(lcd_enabled, int, 0000);
-MODULE_PARM_DESC(lcd_enabled, "Deprecated option, use lcd_type instead");
-
-static int keypad_enabled = -1;
-module_param(keypad_enabled, int, 0000);
-MODULE_PARM_DESC(keypad_enabled, "Deprecated option, use keypad_type instead");
-
-static int lcd_type = -1;
-module_param(lcd_type, int, 0000);
-MODULE_PARM_DESC(lcd_type,
-                "LCD type: 0=none, 1=old //, 2=serial ks0074, 3=hantronix //, 4=nexcom //, 5=compiled-in");
+static int lcd_charset = NOT_SET;
+module_param(lcd_charset, int, 0000);
+MODULE_PARM_DESC(lcd_charset, "LCD character set: 0=standard, 1=KS0074");
 
-static int lcd_proto = -1;
+static int lcd_proto = NOT_SET;
 module_param(lcd_proto, int, 0000);
 MODULE_PARM_DESC(lcd_proto,
                 "LCD communication: 0=parallel (//), 1=serial, 2=TI LCD Interface");
 
-static int lcd_charset = -1;
-module_param(lcd_charset, int, 0000);
-MODULE_PARM_DESC(lcd_charset, "LCD character set: 0=standard, 1=KS0074");
-
-static int keypad_type = -1;
-module_param(keypad_type, int, 0000);
-MODULE_PARM_DESC(keypad_type,
-                "Keypad type: 0=none, 1=old 6 keys, 2=new 6+1 keys, 3=nexcom 4 keys");
-
-static int profile = DEFAULT_PROFILE;
-module_param(profile, int, 0000);
-MODULE_PARM_DESC(profile,
-                "1=16x2 old kp; 2=serial 16x2, new kp; 3=16x2 hantronix; "
-                "4=16x2 nexcom; default=40x2, old kp");
-
 /*
  * These are the parallel port pins the LCD control signals are connected to.
  * Set this to 0 if the signal is not used. Set it to its opposite value
@@ -503,20 +529,31 @@ module_param(lcd_rw_pin, int, 0000);
 MODULE_PARM_DESC(lcd_rw_pin,
                 "# of the // port pin connected to LCD 'RW' signal, with polarity (-17..17)");
 
-static int lcd_bl_pin = PIN_NOT_SET;
-module_param(lcd_bl_pin, int, 0000);
-MODULE_PARM_DESC(lcd_bl_pin,
-                "# of the // port pin connected to LCD backlight, with polarity (-17..17)");
+static int lcd_cl_pin = PIN_NOT_SET;
+module_param(lcd_cl_pin, int, 0000);
+MODULE_PARM_DESC(lcd_cl_pin,
+                "# of the // port pin connected to serial LCD 'SCL' signal, with polarity (-17..17)");
 
 static int lcd_da_pin = PIN_NOT_SET;
 module_param(lcd_da_pin, int, 0000);
 MODULE_PARM_DESC(lcd_da_pin,
                 "# of the // port pin connected to serial LCD 'SDA' signal, with polarity (-17..17)");
 
-static int lcd_cl_pin = PIN_NOT_SET;
-module_param(lcd_cl_pin, int, 0000);
-MODULE_PARM_DESC(lcd_cl_pin,
-                "# of the // port pin connected to serial LCD 'SCL' signal, with polarity (-17..17)");
+static int lcd_bl_pin = PIN_NOT_SET;
+module_param(lcd_bl_pin, int, 0000);
+MODULE_PARM_DESC(lcd_bl_pin,
+                "# of the // port pin connected to LCD backlight, with polarity (-17..17)");
+
+/* Deprecated module parameters - consider not using them anymore */
+
+static int lcd_enabled = NOT_SET;
+module_param(lcd_enabled, int, 0000);
+MODULE_PARM_DESC(lcd_enabled, "Deprecated option, use lcd_type instead");
+
+static int keypad_enabled = NOT_SET;
+module_param(keypad_enabled, int, 0000);
+MODULE_PARM_DESC(keypad_enabled, "Deprecated option, use keypad_type instead");
+
 
 static const unsigned char *lcd_char_conv;
 
@@ -748,7 +785,7 @@ static void lcd_send_serial(int byte)
 /* turn the backlight on or off */
 static void lcd_backlight(int on)
 {
-       if (lcd_bl_pin == PIN_NONE)
+       if (lcd.pins.bl == PIN_NONE)
                return;
 
        /* The backlight is activated by setting the AUTOFEED line to +5V  */
@@ -847,23 +884,23 @@ static void lcd_write_data_tilcd(int data)
 static void lcd_gotoxy(void)
 {
        lcd_write_cmd(0x80      /* set DDRAM address */
-                     | (lcd_addr_y ? lcd_hwidth : 0)
+                     | (lcd.addr.y ? lcd.hwidth : 0)
                      /* we force the cursor to stay at the end of the
                         line if it wants to go farther */
-                     | ((lcd_addr_x < lcd_bwidth) ? lcd_addr_x &
-                        (lcd_hwidth - 1) : lcd_bwidth - 1));
+                     | ((lcd.addr.x < lcd.bwidth) ? lcd.addr.x &
+                        (lcd.hwidth - 1) : lcd.bwidth - 1));
 }
 
 static void lcd_print(char c)
 {
-       if (lcd_addr_x < lcd_bwidth) {
+       if (lcd.addr.x < lcd.bwidth) {
                if (lcd_char_conv != NULL)
                        c = lcd_char_conv[(unsigned char)c];
                lcd_write_data(c);
-               lcd_addr_x++;
+               lcd.addr.x++;
        }
        /* prevents the cursor from wrapping onto the next line */
-       if (lcd_addr_x == lcd_bwidth)
+       if (lcd.addr.x == lcd.bwidth)
                lcd_gotoxy();
 }
 
@@ -872,12 +909,12 @@ static void lcd_clear_fast_s(void)
 {
        int pos;
 
-       lcd_addr_x = 0;
-       lcd_addr_y = 0;
+       lcd.addr.x = 0;
+       lcd.addr.y = 0;
        lcd_gotoxy();
 
        spin_lock_irq(&pprt_lock);
-       for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) {
+       for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) {
                lcd_send_serial(0x5F);  /* R/W=W, RS=1 */
                lcd_send_serial(' ' & 0x0F);
                lcd_send_serial((' ' >> 4) & 0x0F);
@@ -885,8 +922,8 @@ static void lcd_clear_fast_s(void)
        }
        spin_unlock_irq(&pprt_lock);
 
-       lcd_addr_x = 0;
-       lcd_addr_y = 0;
+       lcd.addr.x = 0;
+       lcd.addr.y = 0;
        lcd_gotoxy();
 }
 
@@ -895,12 +932,12 @@ static void lcd_clear_fast_p8(void)
 {
        int pos;
 
-       lcd_addr_x = 0;
-       lcd_addr_y = 0;
+       lcd.addr.x = 0;
+       lcd.addr.y = 0;
        lcd_gotoxy();
 
        spin_lock_irq(&pprt_lock);
-       for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) {
+       for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) {
                /* present the data to the data port */
                w_dtr(pprt, ' ');
 
@@ -923,8 +960,8 @@ static void lcd_clear_fast_p8(void)
        }
        spin_unlock_irq(&pprt_lock);
 
-       lcd_addr_x = 0;
-       lcd_addr_y = 0;
+       lcd.addr.x = 0;
+       lcd.addr.y = 0;
        lcd_gotoxy();
 }
 
@@ -933,12 +970,12 @@ static void lcd_clear_fast_tilcd(void)
 {
        int pos;
 
-       lcd_addr_x = 0;
-       lcd_addr_y = 0;
+       lcd.addr.x = 0;
+       lcd.addr.y = 0;
        lcd_gotoxy();
 
        spin_lock_irq(&pprt_lock);
-       for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) {
+       for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) {
                /* present the data to the data port */
                w_dtr(pprt, ' ');
                udelay(60);
@@ -946,8 +983,8 @@ static void lcd_clear_fast_tilcd(void)
 
        spin_unlock_irq(&pprt_lock);
 
-       lcd_addr_x = 0;
-       lcd_addr_y = 0;
+       lcd.addr.x = 0;
+       lcd.addr.y = 0;
        lcd_gotoxy();
 }
 
@@ -955,15 +992,15 @@ static void lcd_clear_fast_tilcd(void)
 static void lcd_clear_display(void)
 {
        lcd_write_cmd(0x01);    /* clear display */
-       lcd_addr_x = 0;
-       lcd_addr_y = 0;
+       lcd.addr.x = 0;
+       lcd.addr.y = 0;
        /* we must wait a few milliseconds (15) */
        long_sleep(15);
 }
 
 static void lcd_init_display(void)
 {
-       lcd_flags = ((lcd_height > 1) ? LCD_FLAG_N : 0)
+       lcd.flags = ((lcd.height > 1) ? LCD_FLAG_N : 0)
            | LCD_FLAG_D | LCD_FLAG_C | LCD_FLAG_B;
 
        long_sleep(20);         /* wait 20 ms after power-up for the paranoid */
@@ -976,8 +1013,8 @@ static void lcd_init_display(void)
        long_sleep(10);
 
        lcd_write_cmd(0x30      /* set font height and lines number */
-                     | ((lcd_flags & LCD_FLAG_F) ? 4 : 0)
-                     | ((lcd_flags & LCD_FLAG_N) ? 8 : 0)
+                     | ((lcd.flags & LCD_FLAG_F) ? 4 : 0)
+                     | ((lcd.flags & LCD_FLAG_N) ? 8 : 0)
            );
        long_sleep(10);
 
@@ -985,12 +1022,12 @@ static void lcd_init_display(void)
        long_sleep(10);
 
        lcd_write_cmd(0x08      /* set display mode */
-                     | ((lcd_flags & LCD_FLAG_D) ? 4 : 0)
-                     | ((lcd_flags & LCD_FLAG_C) ? 2 : 0)
-                     | ((lcd_flags & LCD_FLAG_B) ? 1 : 0)
+                     | ((lcd.flags & LCD_FLAG_D) ? 4 : 0)
+                     | ((lcd.flags & LCD_FLAG_C) ? 2 : 0)
+                     | ((lcd.flags & LCD_FLAG_B) ? 1 : 0)
            );
 
-       lcd_backlight((lcd_flags & LCD_FLAG_L) ? 1 : 0);
+       lcd_backlight((lcd.flags & LCD_FLAG_L) ? 1 : 0);
 
        long_sleep(10);
 
@@ -1013,100 +1050,99 @@ static inline int handle_lcd_special_code(void)
 
        int processed = 0;
 
-       char *esc = lcd_escape + 2;
-       int oldflags = lcd_flags;
+       char *esc = lcd.esc_seq.buf + 2;
+       int oldflags = lcd.flags;
 
        /* check for display mode flags */
        switch (*esc) {
        case 'D':       /* Display ON */
-               lcd_flags |= LCD_FLAG_D;
+               lcd.flags |= LCD_FLAG_D;
                processed = 1;
                break;
        case 'd':       /* Display OFF */
-               lcd_flags &= ~LCD_FLAG_D;
+               lcd.flags &= ~LCD_FLAG_D;
                processed = 1;
                break;
        case 'C':       /* Cursor ON */
-               lcd_flags |= LCD_FLAG_C;
+               lcd.flags |= LCD_FLAG_C;
                processed = 1;
                break;
        case 'c':       /* Cursor OFF */
-               lcd_flags &= ~LCD_FLAG_C;
+               lcd.flags &= ~LCD_FLAG_C;
                processed = 1;
                break;
        case 'B':       /* Blink ON */
-               lcd_flags |= LCD_FLAG_B;
+               lcd.flags |= LCD_FLAG_B;
                processed = 1;
                break;
        case 'b':       /* Blink OFF */
-               lcd_flags &= ~LCD_FLAG_B;
+               lcd.flags &= ~LCD_FLAG_B;
                processed = 1;
                break;
        case '+':       /* Back light ON */
-               lcd_flags |= LCD_FLAG_L;
+               lcd.flags |= LCD_FLAG_L;
                processed = 1;
                break;
        case '-':       /* Back light OFF */
-               lcd_flags &= ~LCD_FLAG_L;
+               lcd.flags &= ~LCD_FLAG_L;
                processed = 1;
                break;
        case '*':
                /* flash back light using the keypad timer */
                if (scan_timer.function != NULL) {
-                       if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0))
+                       if (lcd.light_tempo == 0
+                                       && ((lcd.flags & LCD_FLAG_L) == 0))
                                lcd_backlight(1);
-                       light_tempo = FLASH_LIGHT_TEMPO;
+                       lcd.light_tempo = FLASH_LIGHT_TEMPO;
                }
                processed = 1;
                break;
        case 'f':       /* Small Font */
-               lcd_flags &= ~LCD_FLAG_F;
+               lcd.flags &= ~LCD_FLAG_F;
                processed = 1;
                break;
        case 'F':       /* Large Font */
-               lcd_flags |= LCD_FLAG_F;
+               lcd.flags |= LCD_FLAG_F;
                processed = 1;
                break;
        case 'n':       /* One Line */
-               lcd_flags &= ~LCD_FLAG_N;
+               lcd.flags &= ~LCD_FLAG_N;
                processed = 1;
                break;
        case 'N':       /* Two Lines */
-               lcd_flags |= LCD_FLAG_N;
+               lcd.flags |= LCD_FLAG_N;
                break;
        case 'l':       /* Shift Cursor Left */
-               if (lcd_addr_x > 0) {
+               if (lcd.addr.x > 0) {
                        /* back one char if not at end of line */
-                       if (lcd_addr_x < lcd_bwidth)
+                       if (lcd.addr.x < lcd.bwidth)
                                lcd_write_cmd(0x10);
-                       lcd_addr_x--;
+                       lcd.addr.x--;
                }
                processed = 1;
                break;
        case 'r':       /* shift cursor right */
-               if (lcd_addr_x < lcd_width) {
+               if (lcd.addr.x < lcd.width) {
                        /* allow the cursor to pass the end of the line */
-                       if (lcd_addr_x <
-                           (lcd_bwidth - 1))
+                       if (lcd.addr.x <
+                           (lcd.bwidth - 1))
                                lcd_write_cmd(0x14);
-                       lcd_addr_x++;
+                       lcd.addr.x++;
                }
                processed = 1;
                break;
        case 'L':       /* shift display left */
-               lcd_left_shift++;
                lcd_write_cmd(0x18);
                processed = 1;
                break;
        case 'R':       /* shift display right */
-               lcd_left_shift--;
                lcd_write_cmd(0x1C);
                processed = 1;
                break;
        case 'k': {     /* kill end of line */
                int x;
 
-               for (x = lcd_addr_x; x < lcd_bwidth; x++)
+               for (x = lcd.addr.x; x < lcd.bwidth; x++)
                        lcd_write_data(' ');
 
                /* restore cursor position */
@@ -1116,7 +1152,6 @@ static inline int handle_lcd_special_code(void)
        }
        case 'I':       /* reinitialize display */
                lcd_init_display();
-               lcd_left_shift = 0;
                processed = 1;
                break;
        case 'G': {
@@ -1187,11 +1222,11 @@ static inline int handle_lcd_special_code(void)
                while (*esc) {
                        if (*esc == 'x') {
                                esc++;
-                               if (kstrtoul(esc, 10, &lcd_addr_x) < 0)
+                               if (kstrtoul(esc, 10, &lcd.addr.x) < 0)
                                        break;
                        } else if (*esc == 'y') {
                                esc++;
-                               if (kstrtoul(esc, 10, &lcd_addr_y) < 0)
+                               if (kstrtoul(esc, 10, &lcd.addr.y) < 0)
                                        break;
                        } else {
                                break;
@@ -1204,25 +1239,25 @@ static inline int handle_lcd_special_code(void)
        }
 
        /* Check whether one flag was changed */
-       if (oldflags != lcd_flags) {
+       if (oldflags != lcd.flags) {
                /* check whether one of B,C,D flags were changed */
-               if ((oldflags ^ lcd_flags) &
+               if ((oldflags ^ lcd.flags) &
                    (LCD_FLAG_B | LCD_FLAG_C | LCD_FLAG_D))
                        /* set display mode */
                        lcd_write_cmd(0x08
-                                     | ((lcd_flags & LCD_FLAG_D) ? 4 : 0)
-                                     | ((lcd_flags & LCD_FLAG_C) ? 2 : 0)
-                                     | ((lcd_flags & LCD_FLAG_B) ? 1 : 0));
+                                     | ((lcd.flags & LCD_FLAG_D) ? 4 : 0)
+                                     | ((lcd.flags & LCD_FLAG_C) ? 2 : 0)
+                                     | ((lcd.flags & LCD_FLAG_B) ? 1 : 0));
                /* check whether one of F,N flags was changed */
-               else if ((oldflags ^ lcd_flags) & (LCD_FLAG_F | LCD_FLAG_N))
+               else if ((oldflags ^ lcd.flags) & (LCD_FLAG_F | LCD_FLAG_N))
                        lcd_write_cmd(0x30
-                                     | ((lcd_flags & LCD_FLAG_F) ? 4 : 0)
-                                     | ((lcd_flags & LCD_FLAG_N) ? 8 : 0));
+                                     | ((lcd.flags & LCD_FLAG_F) ? 4 : 0)
+                                     | ((lcd.flags & LCD_FLAG_N) ? 8 : 0));
                /* check whether L flag was changed */
-               else if ((oldflags ^ lcd_flags) & (LCD_FLAG_L)) {
-                       if (lcd_flags & (LCD_FLAG_L))
+               else if ((oldflags ^ lcd.flags) & (LCD_FLAG_L)) {
+                       if (lcd.flags & (LCD_FLAG_L))
                                lcd_backlight(1);
-                       else if (light_tempo == 0)
+                       else if (lcd.light_tempo == 0)
                                /* switch off the light only when the tempo
                                   lighting is gone */
                                lcd_backlight(0);
@@ -1235,29 +1270,29 @@ static inline int handle_lcd_special_code(void)
 static void lcd_write_char(char c)
 {
        /* first, we'll test if we're in escape mode */
-       if ((c != '\n') && lcd_escape_len >= 0) {
+       if ((c != '\n') && lcd.esc_seq.len >= 0) {
                /* yes, let's add this char to the buffer */
-               lcd_escape[lcd_escape_len++] = c;
-               lcd_escape[lcd_escape_len] = 0;
+               lcd.esc_seq.buf[lcd.esc_seq.len++] = c;
+               lcd.esc_seq.buf[lcd.esc_seq.len] = 0;
        } else {
                /* aborts any previous escape sequence */
-               lcd_escape_len = -1;
+               lcd.esc_seq.len = -1;
 
                switch (c) {
                case LCD_ESCAPE_CHAR:
                        /* start of an escape sequence */
-                       lcd_escape_len = 0;
-                       lcd_escape[lcd_escape_len] = 0;
+                       lcd.esc_seq.len = 0;
+                       lcd.esc_seq.buf[lcd.esc_seq.len] = 0;
                        break;
                case '\b':
                        /* go back one char and clear it */
-                       if (lcd_addr_x > 0) {
+                       if (lcd.addr.x > 0) {
                                /* check if we're not at the
                                   end of the line */
-                               if (lcd_addr_x < lcd_bwidth)
+                               if (lcd.addr.x < lcd.bwidth)
                                        /* back one char */
                                        lcd_write_cmd(0x10);
-                               lcd_addr_x--;
+                               lcd.addr.x--;
                        }
                        /* replace with a space */
                        lcd_write_data(' ');
@@ -1271,15 +1306,15 @@ static void lcd_write_char(char c)
                case '\n':
                        /* flush the remainder of the current line and
                           go to the beginning of the next line */
-                       for (; lcd_addr_x < lcd_bwidth; lcd_addr_x++)
+                       for (; lcd.addr.x < lcd.bwidth; lcd.addr.x++)
                                lcd_write_data(' ');
-                       lcd_addr_x = 0;
-                       lcd_addr_y = (lcd_addr_y + 1) % lcd_height;
+                       lcd.addr.x = 0;
+                       lcd.addr.y = (lcd.addr.y + 1) % lcd.height;
                        lcd_gotoxy();
                        break;
                case '\r':
                        /* go to the beginning of the same line */
-                       lcd_addr_x = 0;
+                       lcd.addr.x = 0;
                        lcd_gotoxy();
                        break;
                case '\t':
@@ -1295,32 +1330,32 @@ static void lcd_write_char(char c)
 
        /* now we'll see if we're in an escape mode and if the current
           escape sequence can be understood. */
-       if (lcd_escape_len >= 2) {
+       if (lcd.esc_seq.len >= 2) {
                int processed = 0;
 
-               if (!strcmp(lcd_escape, "[2J")) {
+               if (!strcmp(lcd.esc_seq.buf, "[2J")) {
                        /* clear the display */
                        lcd_clear_fast();
                        processed = 1;
-               } else if (!strcmp(lcd_escape, "[H")) {
+               } else if (!strcmp(lcd.esc_seq.buf, "[H")) {
                        /* cursor to home */
-                       lcd_addr_x = 0;
-                       lcd_addr_y = 0;
+                       lcd.addr.x = 0;
+                       lcd.addr.y = 0;
                        lcd_gotoxy();
                        processed = 1;
                }
                /* codes starting with ^[[L */
-               else if ((lcd_escape_len >= 3) &&
-                        (lcd_escape[0] == '[') &&
-                        (lcd_escape[1] == 'L')) {
+               else if ((lcd.esc_seq.len >= 3) &&
+                        (lcd.esc_seq.buf[0] == '[') &&
+                        (lcd.esc_seq.buf[1] == 'L')) {
                        processed = handle_lcd_special_code();
                }
 
                /* LCD special escape codes */
                /* flush the escape sequence if it's been processed
                   or if it is getting too long. */
-               if (processed || (lcd_escape_len >= LCD_ESCAPE_LEN))
-                       lcd_escape_len = -1;
+               if (processed || (lcd.esc_seq.len >= LCD_ESCAPE_LEN))
+                       lcd.esc_seq.len = -1;
        } /* escape codes */
 }
 
@@ -1347,23 +1382,22 @@ static ssize_t lcd_write(struct file *file,
 
 static int lcd_open(struct inode *inode, struct file *file)
 {
-       if (lcd_open_cnt)
+       if (!atomic_dec_and_test(&lcd_available))
                return -EBUSY;  /* open only once at a time */
 
        if (file->f_mode & FMODE_READ)  /* device is write-only */
                return -EPERM;
 
-       if (lcd_must_clear) {
+       if (lcd.must_clear) {
                lcd_clear_display();
-               lcd_must_clear = 0;
+               lcd.must_clear = false;
        }
-       lcd_open_cnt++;
        return nonseekable_open(inode, file);
 }
 
 static int lcd_release(struct inode *inode, struct file *file)
 {
-       lcd_open_cnt--;
+       atomic_inc(&lcd_available);
        return 0;
 }
 
@@ -1375,9 +1409,9 @@ static const struct file_operations lcd_fops = {
 };
 
 static struct miscdevice lcd_dev = {
-       LCD_MINOR,
-       "lcd",
-       &lcd_fops
+       .minor  = LCD_MINOR,
+       .name   = "lcd",
+       .fops   = &lcd_fops,
 };
 
 /* public function usable from the kernel for any purpose */
@@ -1386,7 +1420,7 @@ static void panel_lcd_print(const char *s)
        const char *tmp = s;
        int count = strlen(s);
 
-       if (lcd_enabled && lcd_initialized) {
+       if (lcd.enabled && lcd.initialized) {
                for (; count-- > 0; tmp++) {
                        if (!in_interrupt() && (((count + 1) & 0x1f) == 0))
                                /* let's be a little nice with other processes
@@ -1401,183 +1435,173 @@ static void panel_lcd_print(const char *s)
 /* initialize the LCD driver */
 static void lcd_init(void)
 {
-       switch (lcd_type) {
+       switch (selected_lcd_type) {
        case LCD_TYPE_OLD:
                /* parallel mode, 8 bits */
-               if (lcd_proto < 0)
-                       lcd_proto = LCD_PROTO_PARALLEL;
-               if (lcd_charset < 0)
-                       lcd_charset = LCD_CHARSET_NORMAL;
-               if (lcd_e_pin == PIN_NOT_SET)
-                       lcd_e_pin = PIN_STROBE;
-               if (lcd_rs_pin == PIN_NOT_SET)
-                       lcd_rs_pin = PIN_AUTOLF;
-
-               if (lcd_width < 0)
-                       lcd_width = 40;
-               if (lcd_bwidth < 0)
-                       lcd_bwidth = 40;
-               if (lcd_hwidth < 0)
-                       lcd_hwidth = 64;
-               if (lcd_height < 0)
-                       lcd_height = 2;
+               lcd.proto = LCD_PROTO_PARALLEL;
+               lcd.charset = LCD_CHARSET_NORMAL;
+               lcd.pins.e = PIN_STROBE;
+               lcd.pins.rs = PIN_AUTOLF;
+
+               lcd.width = 40;
+               lcd.bwidth = 40;
+               lcd.hwidth = 64;
+               lcd.height = 2;
                break;
        case LCD_TYPE_KS0074:
                /* serial mode, ks0074 */
-               if (lcd_proto < 0)
-                       lcd_proto = LCD_PROTO_SERIAL;
-               if (lcd_charset < 0)
-                       lcd_charset = LCD_CHARSET_KS0074;
-               if (lcd_bl_pin == PIN_NOT_SET)
-                       lcd_bl_pin = PIN_AUTOLF;
-               if (lcd_cl_pin == PIN_NOT_SET)
-                       lcd_cl_pin = PIN_STROBE;
-               if (lcd_da_pin == PIN_NOT_SET)
-                       lcd_da_pin = PIN_D0;
-
-               if (lcd_width < 0)
-                       lcd_width = 16;
-               if (lcd_bwidth < 0)
-                       lcd_bwidth = 40;
-               if (lcd_hwidth < 0)
-                       lcd_hwidth = 16;
-               if (lcd_height < 0)
-                       lcd_height = 2;
+               lcd.proto = LCD_PROTO_SERIAL;
+               lcd.charset = LCD_CHARSET_KS0074;
+               lcd.pins.bl = PIN_AUTOLF;
+               lcd.pins.cl = PIN_STROBE;
+               lcd.pins.da = PIN_D0;
+
+               lcd.width = 16;
+               lcd.bwidth = 40;
+               lcd.hwidth = 16;
+               lcd.height = 2;
                break;
        case LCD_TYPE_NEXCOM:
                /* parallel mode, 8 bits, generic */
-               if (lcd_proto < 0)
-                       lcd_proto = LCD_PROTO_PARALLEL;
-               if (lcd_charset < 0)
-                       lcd_charset = LCD_CHARSET_NORMAL;
-               if (lcd_e_pin == PIN_NOT_SET)
-                       lcd_e_pin = PIN_AUTOLF;
-               if (lcd_rs_pin == PIN_NOT_SET)
-                       lcd_rs_pin = PIN_SELECP;
-               if (lcd_rw_pin == PIN_NOT_SET)
-                       lcd_rw_pin = PIN_INITP;
-
-               if (lcd_width < 0)
-                       lcd_width = 16;
-               if (lcd_bwidth < 0)
-                       lcd_bwidth = 40;
-               if (lcd_hwidth < 0)
-                       lcd_hwidth = 64;
-               if (lcd_height < 0)
-                       lcd_height = 2;
+               lcd.proto = LCD_PROTO_PARALLEL;
+               lcd.charset = LCD_CHARSET_NORMAL;
+               lcd.pins.e = PIN_AUTOLF;
+               lcd.pins.rs = PIN_SELECP;
+               lcd.pins.rw = PIN_INITP;
+
+               lcd.width = 16;
+               lcd.bwidth = 40;
+               lcd.hwidth = 64;
+               lcd.height = 2;
                break;
        case LCD_TYPE_CUSTOM:
                /* customer-defined */
-               if (lcd_proto < 0)
-                       lcd_proto = DEFAULT_LCD_PROTO;
-               if (lcd_charset < 0)
-                       lcd_charset = DEFAULT_LCD_CHARSET;
+               lcd.proto = DEFAULT_LCD_PROTO;
+               lcd.charset = DEFAULT_LCD_CHARSET;
                /* default geometry will be set later */
                break;
        case LCD_TYPE_HANTRONIX:
                /* parallel mode, 8 bits, hantronix-like */
        default:
-               if (lcd_proto < 0)
-                       lcd_proto = LCD_PROTO_PARALLEL;
-               if (lcd_charset < 0)
-                       lcd_charset = LCD_CHARSET_NORMAL;
-               if (lcd_e_pin == PIN_NOT_SET)
-                       lcd_e_pin = PIN_STROBE;
-               if (lcd_rs_pin == PIN_NOT_SET)
-                       lcd_rs_pin = PIN_SELECP;
-
-               if (lcd_width < 0)
-                       lcd_width = 16;
-               if (lcd_bwidth < 0)
-                       lcd_bwidth = 40;
-               if (lcd_hwidth < 0)
-                       lcd_hwidth = 64;
-               if (lcd_height < 0)
-                       lcd_height = 2;
+               lcd.proto = LCD_PROTO_PARALLEL;
+               lcd.charset = LCD_CHARSET_NORMAL;
+               lcd.pins.e = PIN_STROBE;
+               lcd.pins.rs = PIN_SELECP;
+
+               lcd.width = 16;
+               lcd.bwidth = 40;
+               lcd.hwidth = 64;
+               lcd.height = 2;
                break;
        }
 
+       /* Overwrite with module params set on loading */
+       if (lcd_height != NOT_SET)
+               lcd.height = lcd_height;
+       if (lcd_width != NOT_SET)
+               lcd.width = lcd_width;
+       if (lcd_bwidth != NOT_SET)
+               lcd.bwidth = lcd_bwidth;
+       if (lcd_hwidth != NOT_SET)
+               lcd.hwidth = lcd_hwidth;
+       if (lcd_charset != NOT_SET)
+               lcd.charset = lcd_charset;
+       if (lcd_proto != NOT_SET)
+               lcd.proto = lcd_proto;
+       if (lcd_e_pin != PIN_NOT_SET)
+               lcd.pins.e = lcd_e_pin;
+       if (lcd_rs_pin != PIN_NOT_SET)
+               lcd.pins.rs = lcd_rs_pin;
+       if (lcd_rw_pin != PIN_NOT_SET)
+               lcd.pins.rw = lcd_rw_pin;
+       if (lcd_cl_pin != PIN_NOT_SET)
+               lcd.pins.cl = lcd_cl_pin;
+       if (lcd_da_pin != PIN_NOT_SET)
+               lcd.pins.da = lcd_da_pin;
+       if (lcd_bl_pin != PIN_NOT_SET)
+               lcd.pins.bl = lcd_bl_pin;
+
        /* this is used to catch wrong and default values */
-       if (lcd_width <= 0)
-               lcd_width = DEFAULT_LCD_WIDTH;
-       if (lcd_bwidth <= 0)
-               lcd_bwidth = DEFAULT_LCD_BWIDTH;
-       if (lcd_hwidth <= 0)
-               lcd_hwidth = DEFAULT_LCD_HWIDTH;
-       if (lcd_height <= 0)
-               lcd_height = DEFAULT_LCD_HEIGHT;
-
-       if (lcd_proto == LCD_PROTO_SERIAL) {    /* SERIAL */
+       if (lcd.width <= 0)
+               lcd.width = DEFAULT_LCD_WIDTH;
+       if (lcd.bwidth <= 0)
+               lcd.bwidth = DEFAULT_LCD_BWIDTH;
+       if (lcd.hwidth <= 0)
+               lcd.hwidth = DEFAULT_LCD_HWIDTH;
+       if (lcd.height <= 0)
+               lcd.height = DEFAULT_LCD_HEIGHT;
+
+       if (lcd.proto == LCD_PROTO_SERIAL) {    /* SERIAL */
                lcd_write_cmd = lcd_write_cmd_s;
                lcd_write_data = lcd_write_data_s;
                lcd_clear_fast = lcd_clear_fast_s;
 
-               if (lcd_cl_pin == PIN_NOT_SET)
-                       lcd_cl_pin = DEFAULT_LCD_PIN_SCL;
-               if (lcd_da_pin == PIN_NOT_SET)
-                       lcd_da_pin = DEFAULT_LCD_PIN_SDA;
+               if (lcd.pins.cl == PIN_NOT_SET)
+                       lcd.pins.cl = DEFAULT_LCD_PIN_SCL;
+               if (lcd.pins.da == PIN_NOT_SET)
+                       lcd.pins.da = DEFAULT_LCD_PIN_SDA;
 
-       } else if (lcd_proto == LCD_PROTO_PARALLEL) {   /* PARALLEL */
+       } else if (lcd.proto == LCD_PROTO_PARALLEL) {   /* PARALLEL */
                lcd_write_cmd = lcd_write_cmd_p8;
                lcd_write_data = lcd_write_data_p8;
                lcd_clear_fast = lcd_clear_fast_p8;
 
-               if (lcd_e_pin == PIN_NOT_SET)
-                       lcd_e_pin = DEFAULT_LCD_PIN_E;
-               if (lcd_rs_pin == PIN_NOT_SET)
-                       lcd_rs_pin = DEFAULT_LCD_PIN_RS;
-               if (lcd_rw_pin == PIN_NOT_SET)
-                       lcd_rw_pin = DEFAULT_LCD_PIN_RW;
+               if (lcd.pins.e == PIN_NOT_SET)
+                       lcd.pins.e = DEFAULT_LCD_PIN_E;
+               if (lcd.pins.rs == PIN_NOT_SET)
+                       lcd.pins.rs = DEFAULT_LCD_PIN_RS;
+               if (lcd.pins.rw == PIN_NOT_SET)
+                       lcd.pins.rw = DEFAULT_LCD_PIN_RW;
        } else {
                lcd_write_cmd = lcd_write_cmd_tilcd;
                lcd_write_data = lcd_write_data_tilcd;
                lcd_clear_fast = lcd_clear_fast_tilcd;
        }
 
-       if (lcd_bl_pin == PIN_NOT_SET)
-               lcd_bl_pin = DEFAULT_LCD_PIN_BL;
-
-       if (lcd_e_pin == PIN_NOT_SET)
-               lcd_e_pin = PIN_NONE;
-       if (lcd_rs_pin == PIN_NOT_SET)
-               lcd_rs_pin = PIN_NONE;
-       if (lcd_rw_pin == PIN_NOT_SET)
-               lcd_rw_pin = PIN_NONE;
-       if (lcd_bl_pin == PIN_NOT_SET)
-               lcd_bl_pin = PIN_NONE;
-       if (lcd_cl_pin == PIN_NOT_SET)
-               lcd_cl_pin = PIN_NONE;
-       if (lcd_da_pin == PIN_NOT_SET)
-               lcd_da_pin = PIN_NONE;
-
-       if (lcd_charset < 0)
-               lcd_charset = DEFAULT_LCD_CHARSET;
-
-       if (lcd_charset == LCD_CHARSET_KS0074)
+       if (lcd.pins.bl == PIN_NOT_SET)
+               lcd.pins.bl = DEFAULT_LCD_PIN_BL;
+
+       if (lcd.pins.e == PIN_NOT_SET)
+               lcd.pins.e = PIN_NONE;
+       if (lcd.pins.rs == PIN_NOT_SET)
+               lcd.pins.rs = PIN_NONE;
+       if (lcd.pins.rw == PIN_NOT_SET)
+               lcd.pins.rw = PIN_NONE;
+       if (lcd.pins.bl == PIN_NOT_SET)
+               lcd.pins.bl = PIN_NONE;
+       if (lcd.pins.cl == PIN_NOT_SET)
+               lcd.pins.cl = PIN_NONE;
+       if (lcd.pins.da == PIN_NOT_SET)
+               lcd.pins.da = PIN_NONE;
+
+       if (lcd.charset == NOT_SET)
+               lcd.charset = DEFAULT_LCD_CHARSET;
+
+       if (lcd.charset == LCD_CHARSET_KS0074)
                lcd_char_conv = lcd_char_conv_ks0074;
        else
                lcd_char_conv = NULL;
 
-       if (lcd_bl_pin != PIN_NONE)
+       if (lcd.pins.bl != PIN_NONE)
                init_scan_timer();
 
-       pin_to_bits(lcd_e_pin, lcd_bits[LCD_PORT_D][LCD_BIT_E],
+       pin_to_bits(lcd.pins.e, lcd_bits[LCD_PORT_D][LCD_BIT_E],
                    lcd_bits[LCD_PORT_C][LCD_BIT_E]);
-       pin_to_bits(lcd_rs_pin, lcd_bits[LCD_PORT_D][LCD_BIT_RS],
+       pin_to_bits(lcd.pins.rs, lcd_bits[LCD_PORT_D][LCD_BIT_RS],
                    lcd_bits[LCD_PORT_C][LCD_BIT_RS]);
-       pin_to_bits(lcd_rw_pin, lcd_bits[LCD_PORT_D][LCD_BIT_RW],
+       pin_to_bits(lcd.pins.rw, lcd_bits[LCD_PORT_D][LCD_BIT_RW],
                    lcd_bits[LCD_PORT_C][LCD_BIT_RW]);
-       pin_to_bits(lcd_bl_pin, lcd_bits[LCD_PORT_D][LCD_BIT_BL],
+       pin_to_bits(lcd.pins.bl, lcd_bits[LCD_PORT_D][LCD_BIT_BL],
                    lcd_bits[LCD_PORT_C][LCD_BIT_BL]);
-       pin_to_bits(lcd_cl_pin, lcd_bits[LCD_PORT_D][LCD_BIT_CL],
+       pin_to_bits(lcd.pins.cl, lcd_bits[LCD_PORT_D][LCD_BIT_CL],
                    lcd_bits[LCD_PORT_C][LCD_BIT_CL]);
-       pin_to_bits(lcd_da_pin, lcd_bits[LCD_PORT_D][LCD_BIT_DA],
+       pin_to_bits(lcd.pins.da, lcd_bits[LCD_PORT_D][LCD_BIT_DA],
                    lcd_bits[LCD_PORT_C][LCD_BIT_DA]);
 
        /* before this line, we must NOT send anything to the display.
         * Since lcd_init_display() needs to write data, we have to
         * enable mark the LCD initialized just before. */
-       lcd_initialized = 1;
+       lcd.initialized = true;
        lcd_init_display();
 
        /* display a short message */
@@ -1589,10 +1613,10 @@ static void lcd_init(void)
        panel_lcd_print("\x1b[Lc\x1b[Lb\x1b[L*Linux-" UTS_RELEASE "\nPanel-"
                        PANEL_VERSION);
 #endif
-       lcd_addr_x = 0;
-       lcd_addr_y = 0;
+       lcd.addr.x = 0;
+       lcd.addr.y = 0;
        /* clear the display on the next device opening */
-       lcd_must_clear = 1;
+       lcd.must_clear = true;
        lcd_gotoxy();
 }
 
@@ -1627,20 +1651,19 @@ static ssize_t keypad_read(struct file *file,
 
 static int keypad_open(struct inode *inode, struct file *file)
 {
-       if (keypad_open_cnt)
+       if (!atomic_dec_and_test(&keypad_available))
                return -EBUSY;  /* open only once at a time */
 
        if (file->f_mode & FMODE_WRITE) /* device is read-only */
                return -EPERM;
 
        keypad_buflen = 0;      /* flush the buffer on opening */
-       keypad_open_cnt++;
        return 0;
 }
 
 static int keypad_release(struct inode *inode, struct file *file)
 {
-       keypad_open_cnt--;
+       atomic_inc(&keypad_available);
        return 0;
 }
 
@@ -1652,9 +1675,9 @@ static const struct file_operations keypad_fops = {
 };
 
 static struct miscdevice keypad_dev = {
-       KEYPAD_MINOR,
-       "keypad",
-       &keypad_fops
+       .minor  = KEYPAD_MINOR,
+       .name   = "keypad",
+       .fops   = &keypad_fops,
 };
 
 static void keypad_send_key(const char *string, int max_len)
@@ -1663,7 +1686,7 @@ static void keypad_send_key(const char *string, int max_len)
                return;
 
        /* send the key to the device only if a process is attached to it. */
-       if (keypad_open_cnt > 0) {
+       if (!atomic_read(&keypad_available)) {
                while (max_len-- && keypad_buflen < KEYPAD_BUFFER && *string) {
                        keypad_buffer[(keypad_start + keypad_buflen++) %
                                      KEYPAD_BUFFER] = *string++;
@@ -1917,7 +1940,7 @@ static void panel_process_inputs(void)
 
 static void panel_scan_timer(void)
 {
-       if (keypad_enabled && keypad_initialized) {
+       if (keypad.enabled && keypad_initialized) {
                if (spin_trylock_irq(&pprt_lock)) {
                        phys_scan_contacts();
 
@@ -1929,14 +1952,16 @@ static void panel_scan_timer(void)
                        panel_process_inputs();
        }
 
-       if (lcd_enabled && lcd_initialized) {
+       if (lcd.enabled && lcd.initialized) {
                if (keypressed) {
-                       if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0))
+                       if (lcd.light_tempo == 0
+                                       && ((lcd.flags & LCD_FLAG_L) == 0))
                                lcd_backlight(1);
-                       light_tempo = FLASH_LIGHT_TEMPO;
-               } else if (light_tempo > 0) {
-                       light_tempo--;
-                       if (light_tempo == 0 && ((lcd_flags & LCD_FLAG_L) == 0))
+                       lcd.light_tempo = FLASH_LIGHT_TEMPO;
+               } else if (lcd.light_tempo > 0) {
+                       lcd.light_tempo--;
+                       if (lcd.light_tempo == 0
+                                       && ((lcd.flags & LCD_FLAG_L) == 0))
                                lcd_backlight(0);
                }
        }
@@ -2108,7 +2133,7 @@ static void keypad_init(void)
 static int panel_notify_sys(struct notifier_block *this, unsigned long code,
                            void *unused)
 {
-       if (lcd_enabled && lcd_initialized) {
+       if (lcd.enabled && lcd.initialized) {
                switch (code) {
                case SYS_DOWN:
                        panel_lcd_print
@@ -2164,13 +2189,13 @@ static void panel_attach(struct parport *port)
        /* must init LCD first, just in case an IRQ from the keypad is
         * generated at keypad init
         */
-       if (lcd_enabled) {
+       if (lcd.enabled) {
                lcd_init();
                if (misc_register(&lcd_dev))
                        goto err_unreg_device;
        }
 
-       if (keypad_enabled) {
+       if (keypad.enabled) {
                keypad_init();
                if (misc_register(&keypad_dev))
                        goto err_lcd_unreg;
@@ -2178,7 +2203,7 @@ static void panel_attach(struct parport *port)
        return;
 
 err_lcd_unreg:
-       if (lcd_enabled)
+       if (lcd.enabled)
                misc_deregister(&lcd_dev);
 err_unreg_device:
        parport_unregister_device(pprt);
@@ -2196,14 +2221,14 @@ static void panel_detach(struct parport *port)
                return;
        }
 
-       if (keypad_enabled && keypad_initialized) {
+       if (keypad.enabled && keypad_initialized) {
                misc_deregister(&keypad_dev);
                keypad_initialized = 0;
        }
 
-       if (lcd_enabled && lcd_initialized) {
+       if (lcd.enabled && lcd.initialized) {
                misc_deregister(&lcd_dev);
-               lcd_initialized = 0;
+               lcd.initialized = false;
        }
 
        parport_release(pprt);
@@ -2218,72 +2243,89 @@ static struct parport_driver panel_driver = {
 };
 
 /* init function */
-static int panel_init(void)
+static int __init panel_init_module(void)
 {
-       /* for backwards compatibility */
-       if (keypad_type < 0)
-               keypad_type = keypad_enabled;
-
-       if (lcd_type < 0)
-               lcd_type = lcd_enabled;
-
-       if (parport < 0)
-               parport = DEFAULT_PARPORT;
+       int selected_keypad_type = NOT_SET;
 
        /* take care of an eventual profile */
        switch (profile) {
        case PANEL_PROFILE_CUSTOM:
                /* custom profile */
-               if (keypad_type < 0)
-                       keypad_type = DEFAULT_KEYPAD;
-               if (lcd_type < 0)
-                       lcd_type = DEFAULT_LCD;
+               selected_keypad_type = DEFAULT_KEYPAD_TYPE;
+               selected_lcd_type = DEFAULT_LCD_TYPE;
                break;
        case PANEL_PROFILE_OLD:
                /* 8 bits, 2*16, old keypad */
-               if (keypad_type < 0)
-                       keypad_type = KEYPAD_TYPE_OLD;
-               if (lcd_type < 0)
-                       lcd_type = LCD_TYPE_OLD;
-               if (lcd_width < 0)
+               selected_keypad_type = KEYPAD_TYPE_OLD;
+               selected_lcd_type = LCD_TYPE_OLD;
+
+               /* TODO: This two are a little hacky, sort it out later */
+               if (lcd_width == NOT_SET)
                        lcd_width = 16;
-               if (lcd_hwidth < 0)
+               if (lcd_hwidth == NOT_SET)
                        lcd_hwidth = 16;
                break;
        case PANEL_PROFILE_NEW:
                /* serial, 2*16, new keypad */
-               if (keypad_type < 0)
-                       keypad_type = KEYPAD_TYPE_NEW;
-               if (lcd_type < 0)
-                       lcd_type = LCD_TYPE_KS0074;
+               selected_keypad_type = KEYPAD_TYPE_NEW;
+               selected_lcd_type = LCD_TYPE_KS0074;
                break;
        case PANEL_PROFILE_HANTRONIX:
                /* 8 bits, 2*16 hantronix-like, no keypad */
-               if (keypad_type < 0)
-                       keypad_type = KEYPAD_TYPE_NONE;
-               if (lcd_type < 0)
-                       lcd_type = LCD_TYPE_HANTRONIX;
+               selected_keypad_type = KEYPAD_TYPE_NONE;
+               selected_lcd_type = LCD_TYPE_HANTRONIX;
                break;
        case PANEL_PROFILE_NEXCOM:
                /* generic 8 bits, 2*16, nexcom keypad, eg. Nexcom. */
-               if (keypad_type < 0)
-                       keypad_type = KEYPAD_TYPE_NEXCOM;
-               if (lcd_type < 0)
-                       lcd_type = LCD_TYPE_NEXCOM;
+               selected_keypad_type = KEYPAD_TYPE_NEXCOM;
+               selected_lcd_type = LCD_TYPE_NEXCOM;
                break;
        case PANEL_PROFILE_LARGE:
                /* 8 bits, 2*40, old keypad */
-               if (keypad_type < 0)
-                       keypad_type = KEYPAD_TYPE_OLD;
-               if (lcd_type < 0)
-                       lcd_type = LCD_TYPE_OLD;
+               selected_keypad_type = KEYPAD_TYPE_OLD;
+               selected_lcd_type = LCD_TYPE_OLD;
                break;
        }
 
-       lcd_enabled = (lcd_type > 0);
-       keypad_enabled = (keypad_type > 0);
+       /*
+        * Init lcd struct with load-time values to preserve exact current
+        * functionality (at least for now).
+        */
+       lcd.height = lcd_height;
+       lcd.width = lcd_width;
+       lcd.bwidth = lcd_bwidth;
+       lcd.hwidth = lcd_hwidth;
+       lcd.charset = lcd_charset;
+       lcd.proto = lcd_proto;
+       lcd.pins.e = lcd_e_pin;
+       lcd.pins.rs = lcd_rs_pin;
+       lcd.pins.rw = lcd_rw_pin;
+       lcd.pins.cl = lcd_cl_pin;
+       lcd.pins.da = lcd_da_pin;
+       lcd.pins.bl = lcd_bl_pin;
+
+       /* Leave it for now, just in case */
+       lcd.esc_seq.len = -1;
+
+       /*
+        * Overwrite selection with module param values (both keypad and lcd),
+        * where the deprecated params have lower prio.
+        */
+       if (keypad_enabled != NOT_SET)
+               selected_keypad_type = keypad_enabled;
+       if (keypad_type != NOT_SET)
+               selected_keypad_type = keypad_type;
 
-       switch (keypad_type) {
+       keypad.enabled = (selected_keypad_type > 0);
+
+       if (lcd_enabled != NOT_SET)
+               selected_lcd_type = lcd_enabled;
+       if (lcd_type != NOT_SET)
+               selected_lcd_type = lcd_type;
+
+       lcd.enabled = (selected_lcd_type > 0);
+
+       switch (selected_keypad_type) {
        case KEYPAD_TYPE_OLD:
                keypad_profile = old_keypad_profile;
                break;
@@ -2306,7 +2348,7 @@ static int panel_init(void)
                return -EIO;
        }
 
-       if (!lcd_enabled && !keypad_enabled) {
+       if (!lcd.enabled && !keypad.enabled) {
                /* no device enabled, let's release the parport */
                if (pprt) {
                        parport_release(pprt);
@@ -2333,11 +2375,6 @@ static int panel_init(void)
        return 0;
 }
 
-static int __init panel_init_module(void)
-{
-       return panel_init();
-}
-
 static void __exit panel_cleanup_module(void)
 {
        unregister_reboot_notifier(&panel_notifier);
@@ -2346,16 +2383,16 @@ static void __exit panel_cleanup_module(void)
                del_timer_sync(&scan_timer);
 
        if (pprt != NULL) {
-               if (keypad_enabled) {
+               if (keypad.enabled) {
                        misc_deregister(&keypad_dev);
                        keypad_initialized = 0;
                }
 
-               if (lcd_enabled) {
+               if (lcd.enabled) {
                        panel_lcd_print("\x0cLCD driver " PANEL_VERSION
                                        "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-");
                        misc_deregister(&lcd_dev);
-                       lcd_initialized = 0;
+                       lcd.initialized = false;
                }
 
                /* TODO: free all input signals */
This page took 0.058275 seconds and 5 git commands to generate.