Merge tag 'tty-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

Pull tty/serial driver updates from Greg KH:
 "Here's the tty and serial driver patches for 4.2-rc1.

  A number of individual driver updates, some code cleanups, and other
  minor things, full details in the shortlog.

  All have been in linux-next for a while with no reported issues"

* tag 'tty-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (152 commits)
  Doc: serial-rs485.txt: update RS485 driver interface
  Doc: tty.txt: remove mention of the BKL
  MAINTAINERS: tty: add serial docs directory
  serial: sprd: check for NULL after calling devm_clk_get
  serial: 8250_pci: Correct uartclk for xr17v35x expansion chips
  serial: 8250_pci: Add support for 12 port Exar boards
  serial: 8250_uniphier: add bindings document for UniPhier UART
  serial: core: cleanup in uart_get_baud_rate()
  serial: stm32-usart: Add STM32 USART Driver
  tty/serial: kill off set_irq_flags usage
  tty: move linux/gsmmux.h to uapi
  doc: dt: add documentation for nxp,lpc1850-uart
  serial: 8250: add LPC18xx/43xx UART driver
  serial: 8250_uniphier: add UniPhier serial driver
  serial: 8250_dw: support ACPI platforms with integrated DMA engine
  serial: of_serial: check the return value of clk_prepare_enable()
  serial: of_serial: use devm_clk_get() instead of clk_get()
  serial: earlycon: Add support for big-endian MMIO accesses
  serial: sirf: use hrtimer for data rx
  serial: sirf: correct the fifo empty_bit
  ...
This commit is contained in:
Linus Torvalds
2015-06-26 15:53:22 -07:00
97 changed files with 3236 additions and 1805 deletions

View File

@@ -261,19 +261,22 @@ u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode)
int m;
if (glyph < 0 || glyph >= MAX_GLYPH)
return 0;
else if (!(p = *conp->vc_uni_pagedir_loc))
return glyph;
else if (use_unicode) {
if (!p->inverse_trans_unicode)
else {
p = *conp->vc_uni_pagedir_loc;
if (!p)
return glyph;
else
return p->inverse_trans_unicode[glyph];
} else {
m = inv_translate[conp->vc_num];
if (!p->inverse_translations[m])
return glyph;
else
return p->inverse_translations[m][glyph];
else if (use_unicode) {
if (!p->inverse_trans_unicode)
return glyph;
else
return p->inverse_trans_unicode[glyph];
} else {
m = inv_translate[conp->vc_num];
if (!p->inverse_translations[m])
return glyph;
else
return p->inverse_translations[m][glyph];
}
}
}
EXPORT_SYMBOL_GPL(inverse_translate);
@@ -397,7 +400,8 @@ static void con_release_unimap(struct uni_pagedir *p)
if (p == dflt) dflt = NULL;
for (i = 0; i < 32; i++) {
if ((p1 = p->uni_pgdir[i]) != NULL) {
p1 = p->uni_pgdir[i];
if (p1 != NULL) {
for (j = 0; j < 32; j++)
kfree(p1[j]);
kfree(p1);
@@ -473,14 +477,16 @@ con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos)
int i, n;
u16 **p1, *p2;
if (!(p1 = p->uni_pgdir[n = unicode >> 11])) {
p1 = p->uni_pgdir[n = unicode >> 11];
if (!p1) {
p1 = p->uni_pgdir[n] = kmalloc(32*sizeof(u16 *), GFP_KERNEL);
if (!p1) return -ENOMEM;
for (i = 0; i < 32; i++)
p1[i] = NULL;
}
if (!(p2 = p1[n = (unicode >> 6) & 0x1f])) {
p2 = p1[n = (unicode >> 6) & 0x1f];
if (!p2) {
p2 = p1[n] = kmalloc(64*sizeof(u16), GFP_KERNEL);
if (!p2) return -ENOMEM;
memset(p2, 0xff, 64*sizeof(u16)); /* No glyphs for the characters (yet) */
@@ -569,10 +575,12 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
* entries from "p" (old) to "q" (new).
*/
l = 0; /* unicode value */
for (i = 0; i < 32; i++)
if ((p1 = p->uni_pgdir[i]))
for (j = 0; j < 32; j++)
if ((p2 = p1[j])) {
for (i = 0; i < 32; i++) {
p1 = p->uni_pgdir[i];
if (p1)
for (j = 0; j < 32; j++) {
p2 = p1[j];
if (p2) {
for (k = 0; k < 64; k++, l++)
if (p2[k] != 0xffff) {
/*
@@ -593,9 +601,11 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
/* Account for row of 64 empty entries */
l += 64;
}
}
else
/* Account for empty table */
l += 32 * 64;
}
/*
* Finished copying font table, set vc_uni_pagedir to new table
@@ -735,10 +745,12 @@ int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct uni
ect = 0;
if (*vc->vc_uni_pagedir_loc) {
p = *vc->vc_uni_pagedir_loc;
for (i = 0; i < 32; i++)
if ((p1 = p->uni_pgdir[i]))
for (j = 0; j < 32; j++)
if ((p2 = *(p1++)))
for (i = 0; i < 32; i++) {
p1 = p->uni_pgdir[i];
if (p1)
for (j = 0; j < 32; j++) {
p2 = *(p1++);
if (p2)
for (k = 0; k < 64; k++) {
if (*p2 < MAX_GLYPH && ect++ < ct) {
__put_user((u_short)((i<<11)+(j<<6)+k),
@@ -749,6 +761,8 @@ int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct uni
}
p2++;
}
}
}
}
__put_user(ect, uct);
console_unlock();

View File

@@ -108,6 +108,7 @@
#define CON_DRIVER_FLAG_MODULE 1
#define CON_DRIVER_FLAG_INIT 2
#define CON_DRIVER_FLAG_ATTR 4
#define CON_DRIVER_FLAG_ZOMBIE 8
struct con_driver {
const struct consw *con;
@@ -135,6 +136,7 @@ const struct consw *conswitchp;
*/
#define DEFAULT_BELL_PITCH 750
#define DEFAULT_BELL_DURATION (HZ/8)
#define DEFAULT_CURSOR_BLINK_MS 200
struct vc vc_cons [MAX_NR_CONSOLES];
@@ -153,6 +155,7 @@ static int set_vesa_blanking(char __user *p);
static void set_cursor(struct vc_data *vc);
static void hide_cursor(struct vc_data *vc);
static void console_callback(struct work_struct *ignored);
static void con_driver_unregister_callback(struct work_struct *ignored);
static void blank_screen_t(unsigned long dummy);
static void set_palette(struct vc_data *vc);
@@ -182,6 +185,7 @@ static int blankinterval = 10*60;
core_param(consoleblank, blankinterval, int, 0444);
static DECLARE_WORK(console_work, console_callback);
static DECLARE_WORK(con_driver_unregister_work, con_driver_unregister_callback);
/*
* fg_console is the current virtual console,
@@ -1590,6 +1594,13 @@ static void setterm_command(struct vc_data *vc)
case 15: /* activate the previous console */
set_console(last_console);
break;
case 16: /* set cursor blink duration in msec */
if (vc->vc_npar >= 1 && vc->vc_par[1] >= 50 &&
vc->vc_par[1] <= USHRT_MAX)
vc->vc_cur_blink_ms = vc->vc_par[1];
else
vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS;
break;
}
}
@@ -1717,6 +1728,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
vc->vc_bell_duration = DEFAULT_BELL_DURATION;
vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS;
gotoxy(vc, 0, 0);
save_cur(vc);
@@ -3192,22 +3204,6 @@ err:
#ifdef CONFIG_VT_HW_CONSOLE_BINDING
static int con_is_graphics(const struct consw *csw, int first, int last)
{
int i, retval = 0;
for (i = first; i <= last; i++) {
struct vc_data *vc = vc_cons[i].d;
if (vc && vc->vc_mode == KD_GRAPHICS) {
retval = 1;
break;
}
}
return retval;
}
/* unlocked version of unbind_con_driver() */
int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
{
@@ -3293,8 +3289,7 @@ static int vt_bind(struct con_driver *con)
const struct consw *defcsw = NULL, *csw = NULL;
int i, more = 1, first = -1, last = -1, deflt = 0;
if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) ||
con_is_graphics(con->con, con->first, con->last))
if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE))
goto err;
csw = con->con;
@@ -3345,8 +3340,7 @@ static int vt_unbind(struct con_driver *con)
int i, more = 1, first = -1, last = -1, deflt = 0;
int ret;
if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) ||
con_is_graphics(con->con, con->first, con->last))
if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE))
goto err;
csw = con->con;
@@ -3596,7 +3590,8 @@ static int do_register_con_driver(const struct consw *csw, int first, int last)
for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
con_driver = &registered_con_driver[i];
if (con_driver->con == NULL) {
if (con_driver->con == NULL &&
!(con_driver->flag & CON_DRIVER_FLAG_ZOMBIE)) {
con_driver->con = csw;
con_driver->desc = desc;
con_driver->node = i;
@@ -3658,16 +3653,20 @@ int do_unregister_con_driver(const struct consw *csw)
struct con_driver *con_driver = &registered_con_driver[i];
if (con_driver->con == csw) {
vtconsole_deinit_device(con_driver);
device_destroy(vtconsole_class,
MKDEV(0, con_driver->node));
/*
* Defer the removal of the sysfs entries since that
* will acquire the kernfs s_active lock and we can't
* acquire this lock while holding the console lock:
* the unbind sysfs entry imposes already the opposite
* order. Reset con already here to prevent any later
* lookup to succeed and mark this slot as zombie, so
* it won't get reused until we complete the removal
* in the deferred work.
*/
con_driver->con = NULL;
con_driver->desc = NULL;
con_driver->dev = NULL;
con_driver->node = 0;
con_driver->flag = 0;
con_driver->first = 0;
con_driver->last = 0;
con_driver->flag = CON_DRIVER_FLAG_ZOMBIE;
schedule_work(&con_driver_unregister_work);
return 0;
}
}
@@ -3676,6 +3675,39 @@ int do_unregister_con_driver(const struct consw *csw)
}
EXPORT_SYMBOL_GPL(do_unregister_con_driver);
static void con_driver_unregister_callback(struct work_struct *ignored)
{
int i;
console_lock();
for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
struct con_driver *con_driver = &registered_con_driver[i];
if (!(con_driver->flag & CON_DRIVER_FLAG_ZOMBIE))
continue;
console_unlock();
vtconsole_deinit_device(con_driver);
device_destroy(vtconsole_class, MKDEV(0, con_driver->node));
console_lock();
if (WARN_ON_ONCE(con_driver->con))
con_driver->con = NULL;
con_driver->desc = NULL;
con_driver->dev = NULL;
con_driver->node = 0;
WARN_ON_ONCE(con_driver->flag != CON_DRIVER_FLAG_ZOMBIE);
con_driver->flag = 0;
con_driver->first = 0;
con_driver->last = 0;
}
console_unlock();
}
/*
* If we support more console drivers, this function is used
* when a driver wants to take over some existing consoles