mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: "There are two memory management related changes, the CMMA support for KVM to avoid swap-in of freed pages and the split page table lock for the PMD level. These two come with common code changes in mm/. A fix for the long standing theoretical TLB flush problem, this one comes with a common code change in kernel/sched/. Another set of changes is Heikos uaccess work, included is the initial set of patches with more to come. And fixes and cleanups as usual" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (36 commits) s390/con3270: optionally disable auto update s390/mm: remove unecessary parameter from pgste_ipte_notify s390/mm: remove unnecessary parameter from gmap_do_ipte_notify s390/mm: fixing comment so that parameter name match s390/smp: limit number of cpus in possible cpu mask hypfs: Add clarification for "weight_min" attribute s390: update defconfigs s390/ptrace: add support for PTRACE_SINGLEBLOCK s390/perf: make print_debug_cf() static s390/topology: Remove call to update_cpu_masks() s390/compat: remove compat exec domain s390: select CONFIG_TTY for use of tty in unconditional keyboard driver s390/appldata_os: fix cpu array size calculation s390/checksum: remove memset() within csum_partial_copy_from_user() s390/uaccess: remove copy_from_user_real() s390/sclp_early: Return correct HSA block count also for zero s390: add some drivers/subsystems to the MAINTAINERS file s390: improve debug feature usage s390/airq: add support for irq ranges s390/mm: enable split page table lock for PMD level ...
This commit is contained in:
commit
1f8c538ed6
61 changed files with 943 additions and 427 deletions
|
|
@ -922,7 +922,7 @@ static int __init con3215_init(void)
|
|||
raw3215_freelist = req;
|
||||
}
|
||||
|
||||
cdev = ccw_device_probe_console();
|
||||
cdev = ccw_device_create_console(&raw3215_ccw_driver);
|
||||
if (IS_ERR(cdev))
|
||||
return -ENODEV;
|
||||
|
||||
|
|
@ -932,6 +932,12 @@ static int __init con3215_init(void)
|
|||
cdev->handler = raw3215_irq;
|
||||
|
||||
raw->flags |= RAW3215_FIXED;
|
||||
if (ccw_device_enable_console(cdev)) {
|
||||
ccw_device_destroy_console(cdev);
|
||||
raw3215_free_info(raw);
|
||||
raw3215[0] = NULL;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Request the console irq */
|
||||
if (raw3215_startup(raw) != 0) {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
* Copyright IBM Corp. 2003, 2009
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
|
@ -30,6 +31,9 @@
|
|||
|
||||
static struct raw3270_fn con3270_fn;
|
||||
|
||||
static bool auto_update = 1;
|
||||
module_param(auto_update, bool, 0);
|
||||
|
||||
/*
|
||||
* Main 3270 console view data structure.
|
||||
*/
|
||||
|
|
@ -204,6 +208,8 @@ con3270_update(struct con3270 *cp)
|
|||
struct string *s, *n;
|
||||
int rc;
|
||||
|
||||
if (!auto_update && !raw3270_view_active(&cp->view))
|
||||
return;
|
||||
if (cp->view.dev)
|
||||
raw3270_activate_view(&cp->view);
|
||||
|
||||
|
|
@ -529,6 +535,7 @@ con3270_flush(void)
|
|||
if (!cp->view.dev)
|
||||
return;
|
||||
raw3270_pm_unfreeze(&cp->view);
|
||||
raw3270_activate_view(&cp->view);
|
||||
spin_lock_irqsave(&cp->view.lock, flags);
|
||||
con3270_wait_write(cp);
|
||||
cp->nr_up = 0;
|
||||
|
|
@ -576,7 +583,6 @@ static struct console con3270 = {
|
|||
static int __init
|
||||
con3270_init(void)
|
||||
{
|
||||
struct ccw_device *cdev;
|
||||
struct raw3270 *rp;
|
||||
void *cbuf;
|
||||
int i;
|
||||
|
|
@ -591,10 +597,7 @@ con3270_init(void)
|
|||
cpcmd("TERM AUTOCR OFF", NULL, 0, NULL);
|
||||
}
|
||||
|
||||
cdev = ccw_device_probe_console();
|
||||
if (IS_ERR(cdev))
|
||||
return -ENODEV;
|
||||
rp = raw3270_setup_console(cdev);
|
||||
rp = raw3270_setup_console();
|
||||
if (IS_ERR(rp))
|
||||
return PTR_ERR(rp);
|
||||
|
||||
|
|
|
|||
|
|
@ -275,6 +275,15 @@ __raw3270_start(struct raw3270 *rp, struct raw3270_view *view,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
raw3270_view_active(struct raw3270_view *view)
|
||||
{
|
||||
struct raw3270 *rp = view->dev;
|
||||
|
||||
return rp && rp->view == view &&
|
||||
!test_bit(RAW3270_FLAGS_FROZEN, &rp->flags);
|
||||
}
|
||||
|
||||
int
|
||||
raw3270_start(struct raw3270_view *view, struct raw3270_request *rq)
|
||||
{
|
||||
|
|
@ -776,22 +785,37 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_TN3270_CONSOLE
|
||||
/* Tentative definition - see below for actual definition. */
|
||||
static struct ccw_driver raw3270_ccw_driver;
|
||||
|
||||
/*
|
||||
* Setup 3270 device configured as console.
|
||||
*/
|
||||
struct raw3270 __init *raw3270_setup_console(struct ccw_device *cdev)
|
||||
struct raw3270 __init *raw3270_setup_console(void)
|
||||
{
|
||||
struct ccw_device *cdev;
|
||||
unsigned long flags;
|
||||
struct raw3270 *rp;
|
||||
char *ascebc;
|
||||
int rc;
|
||||
|
||||
cdev = ccw_device_create_console(&raw3270_ccw_driver);
|
||||
if (IS_ERR(cdev))
|
||||
return ERR_CAST(cdev);
|
||||
|
||||
rp = kzalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA);
|
||||
ascebc = kzalloc(256, GFP_KERNEL);
|
||||
rc = raw3270_setup_device(cdev, rp, ascebc);
|
||||
if (rc)
|
||||
return ERR_PTR(rc);
|
||||
set_bit(RAW3270_FLAGS_CONSOLE, &rp->flags);
|
||||
|
||||
rc = ccw_device_enable_console(cdev);
|
||||
if (rc) {
|
||||
ccw_device_destroy_console(cdev);
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
|
||||
do {
|
||||
__raw3270_reset_device(rp);
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ int raw3270_start_locked(struct raw3270_view *, struct raw3270_request *);
|
|||
int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *);
|
||||
int raw3270_reset(struct raw3270_view *);
|
||||
struct raw3270_view *raw3270_view(struct raw3270_view *);
|
||||
int raw3270_view_active(struct raw3270_view *);
|
||||
|
||||
/* Reference count inliner for view structures. */
|
||||
static inline void
|
||||
|
|
@ -190,7 +191,7 @@ raw3270_put_view(struct raw3270_view *view)
|
|||
wake_up(&raw3270_wait_queue);
|
||||
}
|
||||
|
||||
struct raw3270 *raw3270_setup_console(struct ccw_device *cdev);
|
||||
struct raw3270 *raw3270_setup_console(void);
|
||||
void raw3270_wait_cons_dev(struct raw3270 *);
|
||||
|
||||
/* Notifier for device addition/removal */
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ struct read_info_sccb {
|
|||
struct sccb_header header; /* 0-7 */
|
||||
u16 rnmax; /* 8-9 */
|
||||
u8 rnsize; /* 10 */
|
||||
u8 _reserved0[24 - 11]; /* 11-15 */
|
||||
u8 _reserved0[16 - 11]; /* 11-15 */
|
||||
u16 ncpurl; /* 16-17 */
|
||||
u8 _reserved7[24 - 18]; /* 18-23 */
|
||||
u8 loadparm[8]; /* 24-31 */
|
||||
u8 _reserved1[48 - 32]; /* 32-47 */
|
||||
u64 facilities; /* 48-55 */
|
||||
|
|
@ -32,13 +34,16 @@ struct read_info_sccb {
|
|||
u8 _reserved4[100 - 92]; /* 92-99 */
|
||||
u32 rnsize2; /* 100-103 */
|
||||
u64 rnmax2; /* 104-111 */
|
||||
u8 _reserved5[4096 - 112]; /* 112-4095 */
|
||||
u8 _reserved5[120 - 112]; /* 112-119 */
|
||||
u16 hcpua; /* 120-121 */
|
||||
u8 _reserved6[4096 - 122]; /* 122-4095 */
|
||||
} __packed __aligned(PAGE_SIZE);
|
||||
|
||||
static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata;
|
||||
static unsigned int sclp_con_has_vt220 __initdata;
|
||||
static unsigned int sclp_con_has_linemode __initdata;
|
||||
static unsigned long sclp_hsa_size;
|
||||
static unsigned int sclp_max_cpu;
|
||||
static struct sclp_ipl_info sclp_ipl_info;
|
||||
|
||||
u64 sclp_facilities;
|
||||
|
|
@ -102,6 +107,15 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb)
|
|||
sclp_rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
|
||||
sclp_rzm <<= 20;
|
||||
|
||||
if (!sccb->hcpua) {
|
||||
if (MACHINE_IS_VM)
|
||||
sclp_max_cpu = 64;
|
||||
else
|
||||
sclp_max_cpu = sccb->ncpurl;
|
||||
} else {
|
||||
sclp_max_cpu = sccb->hcpua + 1;
|
||||
}
|
||||
|
||||
/* Save IPL information */
|
||||
sclp_ipl_info.is_valid = 1;
|
||||
if (sccb->flags & 0x2)
|
||||
|
|
@ -129,6 +143,11 @@ unsigned long long sclp_get_rzm(void)
|
|||
return sclp_rzm;
|
||||
}
|
||||
|
||||
unsigned int sclp_get_max_cpu(void)
|
||||
{
|
||||
return sclp_max_cpu;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will be called after sclp_facilities_detect(), which gets
|
||||
* called from early.c code. The sclp_facilities_detect() function retrieves
|
||||
|
|
@ -184,9 +203,9 @@ static long __init sclp_hsa_size_init(struct sdias_sccb *sccb)
|
|||
sccb_init_eq_size(sccb);
|
||||
if (sclp_cmd_early(SCLP_CMDW_WRITE_EVENT_DATA, sccb))
|
||||
return -EIO;
|
||||
if (sccb->evbuf.blk_cnt != 0)
|
||||
return (sccb->evbuf.blk_cnt - 1) * PAGE_SIZE;
|
||||
return 0;
|
||||
if (sccb->evbuf.blk_cnt == 0)
|
||||
return 0;
|
||||
return (sccb->evbuf.blk_cnt - 1) * PAGE_SIZE;
|
||||
}
|
||||
|
||||
static long __init sclp_hsa_copy_wait(struct sccb_header *sccb)
|
||||
|
|
@ -195,6 +214,8 @@ static long __init sclp_hsa_copy_wait(struct sccb_header *sccb)
|
|||
sccb->length = PAGE_SIZE;
|
||||
if (sclp_cmd_early(SCLP_CMDW_READ_EVENT_DATA, sccb))
|
||||
return -EIO;
|
||||
if (((struct sdias_sccb *) sccb)->evbuf.blk_cnt == 0)
|
||||
return 0;
|
||||
return (((struct sdias_sccb *) sccb)->evbuf.blk_cnt - 1) * PAGE_SIZE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -186,55 +186,71 @@ void airq_iv_release(struct airq_iv *iv)
|
|||
EXPORT_SYMBOL(airq_iv_release);
|
||||
|
||||
/**
|
||||
* airq_iv_alloc_bit - allocate an irq bit from an interrupt vector
|
||||
* airq_iv_alloc - allocate irq bits from an interrupt vector
|
||||
* @iv: pointer to an interrupt vector structure
|
||||
* @num: number of consecutive irq bits to allocate
|
||||
*
|
||||
* Returns the bit number of the allocated irq, or -1UL if no bit
|
||||
* is available or the AIRQ_IV_ALLOC flag has not been specified
|
||||
* Returns the bit number of the first irq in the allocated block of irqs,
|
||||
* or -1UL if no bit is available or the AIRQ_IV_ALLOC flag has not been
|
||||
* specified
|
||||
*/
|
||||
unsigned long airq_iv_alloc_bit(struct airq_iv *iv)
|
||||
unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num)
|
||||
{
|
||||
unsigned long bit;
|
||||
unsigned long bit, i;
|
||||
|
||||
if (!iv->avail)
|
||||
if (!iv->avail || num == 0)
|
||||
return -1UL;
|
||||
spin_lock(&iv->lock);
|
||||
bit = find_first_bit_inv(iv->avail, iv->bits);
|
||||
if (bit < iv->bits) {
|
||||
clear_bit_inv(bit, iv->avail);
|
||||
if (bit >= iv->end)
|
||||
iv->end = bit + 1;
|
||||
} else
|
||||
while (bit + num <= iv->bits) {
|
||||
for (i = 1; i < num; i++)
|
||||
if (!test_bit_inv(bit + i, iv->avail))
|
||||
break;
|
||||
if (i >= num) {
|
||||
/* Found a suitable block of irqs */
|
||||
for (i = 0; i < num; i++)
|
||||
clear_bit_inv(bit + i, iv->avail);
|
||||
if (bit + num >= iv->end)
|
||||
iv->end = bit + num + 1;
|
||||
break;
|
||||
}
|
||||
bit = find_next_bit_inv(iv->avail, iv->bits, bit + i + 1);
|
||||
}
|
||||
if (bit + num > iv->bits)
|
||||
bit = -1UL;
|
||||
spin_unlock(&iv->lock);
|
||||
return bit;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(airq_iv_alloc_bit);
|
||||
EXPORT_SYMBOL(airq_iv_alloc);
|
||||
|
||||
/**
|
||||
* airq_iv_free_bit - free an irq bit of an interrupt vector
|
||||
* airq_iv_free - free irq bits of an interrupt vector
|
||||
* @iv: pointer to interrupt vector structure
|
||||
* @bit: number of the irq bit to free
|
||||
* @bit: number of the first irq bit to free
|
||||
* @num: number of consecutive irq bits to free
|
||||
*/
|
||||
void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit)
|
||||
void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num)
|
||||
{
|
||||
if (!iv->avail)
|
||||
unsigned long i;
|
||||
|
||||
if (!iv->avail || num == 0)
|
||||
return;
|
||||
spin_lock(&iv->lock);
|
||||
/* Clear (possibly left over) interrupt bit */
|
||||
clear_bit_inv(bit, iv->vector);
|
||||
/* Make the bit position available again */
|
||||
set_bit_inv(bit, iv->avail);
|
||||
if (bit == iv->end - 1) {
|
||||
for (i = 0; i < num; i++) {
|
||||
/* Clear (possibly left over) interrupt bit */
|
||||
clear_bit_inv(bit + i, iv->vector);
|
||||
/* Make the bit positions available again */
|
||||
set_bit_inv(bit + i, iv->avail);
|
||||
}
|
||||
if (bit + num >= iv->end) {
|
||||
/* Find new end of bit-field */
|
||||
while (--iv->end > 0)
|
||||
if (!test_bit_inv(iv->end - 1, iv->avail))
|
||||
break;
|
||||
while (iv->end > 0 && !test_bit_inv(iv->end - 1, iv->avail))
|
||||
iv->end--;
|
||||
}
|
||||
spin_unlock(&iv->lock);
|
||||
}
|
||||
EXPORT_SYMBOL(airq_iv_free_bit);
|
||||
EXPORT_SYMBOL(airq_iv_free);
|
||||
|
||||
/**
|
||||
* airq_iv_scan - scan interrupt vector for non-zero bits
|
||||
|
|
|
|||
|
|
@ -173,8 +173,7 @@ static struct css_driver chsc_subchannel_driver = {
|
|||
|
||||
static int __init chsc_init_dbfs(void)
|
||||
{
|
||||
chsc_debug_msg_id = debug_register("chsc_msg", 16, 1,
|
||||
16 * sizeof(long));
|
||||
chsc_debug_msg_id = debug_register("chsc_msg", 8, 1, 4 * sizeof(long));
|
||||
if (!chsc_debug_msg_id)
|
||||
goto out;
|
||||
debug_register_view(chsc_debug_msg_id, &debug_sprintf_view);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ debug_info_t *cio_debug_crw_id;
|
|||
*/
|
||||
static int __init cio_debug_init(void)
|
||||
{
|
||||
cio_debug_msg_id = debug_register("cio_msg", 16, 1, 16 * sizeof(long));
|
||||
cio_debug_msg_id = debug_register("cio_msg", 16, 1, 11 * sizeof(long));
|
||||
if (!cio_debug_msg_id)
|
||||
goto out_unregister;
|
||||
debug_register_view(cio_debug_msg_id, &debug_sprintf_view);
|
||||
|
|
@ -64,7 +64,7 @@ static int __init cio_debug_init(void)
|
|||
goto out_unregister;
|
||||
debug_register_view(cio_debug_trace_id, &debug_hex_ascii_view);
|
||||
debug_set_level(cio_debug_trace_id, 2);
|
||||
cio_debug_crw_id = debug_register("cio_crw", 16, 1, 16 * sizeof(long));
|
||||
cio_debug_crw_id = debug_register("cio_crw", 8, 1, 8 * sizeof(long));
|
||||
if (!cio_debug_crw_id)
|
||||
goto out_unregister;
|
||||
debug_register_view(cio_debug_crw_id, &debug_sprintf_view);
|
||||
|
|
|
|||
|
|
@ -1571,12 +1571,27 @@ out:
|
|||
return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CCW_CONSOLE
|
||||
static int ccw_device_console_enable(struct ccw_device *cdev,
|
||||
struct subchannel *sch)
|
||||
static void ccw_device_set_int_class(struct ccw_device *cdev)
|
||||
{
|
||||
struct ccw_driver *cdrv = cdev->drv;
|
||||
|
||||
/* Note: we interpret class 0 in this context as an uninitialized
|
||||
* field since it translates to a non-I/O interrupt class. */
|
||||
if (cdrv->int_class != 0)
|
||||
cdev->private->int_class = cdrv->int_class;
|
||||
else
|
||||
cdev->private->int_class = IRQIO_CIO;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CCW_CONSOLE
|
||||
int __init ccw_device_enable_console(struct ccw_device *cdev)
|
||||
{
|
||||
struct subchannel *sch = to_subchannel(cdev->dev.parent);
|
||||
int rc;
|
||||
|
||||
if (!cdev->drv || !cdev->handler)
|
||||
return -EINVAL;
|
||||
|
||||
io_subchannel_init_fields(sch);
|
||||
rc = cio_commit_config(sch);
|
||||
if (rc)
|
||||
|
|
@ -1609,12 +1624,11 @@ out_unlock:
|
|||
return rc;
|
||||
}
|
||||
|
||||
struct ccw_device *ccw_device_probe_console(void)
|
||||
struct ccw_device * __init ccw_device_create_console(struct ccw_driver *drv)
|
||||
{
|
||||
struct io_subchannel_private *io_priv;
|
||||
struct ccw_device *cdev;
|
||||
struct subchannel *sch;
|
||||
int ret;
|
||||
|
||||
sch = cio_probe_console();
|
||||
if (IS_ERR(sch))
|
||||
|
|
@ -1631,18 +1645,23 @@ struct ccw_device *ccw_device_probe_console(void)
|
|||
kfree(io_priv);
|
||||
return cdev;
|
||||
}
|
||||
cdev->drv = drv;
|
||||
set_io_private(sch, io_priv);
|
||||
ret = ccw_device_console_enable(cdev, sch);
|
||||
if (ret) {
|
||||
set_io_private(sch, NULL);
|
||||
put_device(&sch->dev);
|
||||
put_device(&cdev->dev);
|
||||
kfree(io_priv);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
ccw_device_set_int_class(cdev);
|
||||
return cdev;
|
||||
}
|
||||
|
||||
void __init ccw_device_destroy_console(struct ccw_device *cdev)
|
||||
{
|
||||
struct subchannel *sch = to_subchannel(cdev->dev.parent);
|
||||
struct io_subchannel_private *io_priv = to_io_private(sch);
|
||||
|
||||
set_io_private(sch, NULL);
|
||||
put_device(&sch->dev);
|
||||
put_device(&cdev->dev);
|
||||
kfree(io_priv);
|
||||
}
|
||||
|
||||
/**
|
||||
* ccw_device_wait_idle() - busy wait for device to become idle
|
||||
* @cdev: ccw device
|
||||
|
|
@ -1726,15 +1745,8 @@ ccw_device_probe (struct device *dev)
|
|||
int ret;
|
||||
|
||||
cdev->drv = cdrv; /* to let the driver call _set_online */
|
||||
/* Note: we interpret class 0 in this context as an uninitialized
|
||||
* field since it translates to a non-I/O interrupt class. */
|
||||
if (cdrv->int_class != 0)
|
||||
cdev->private->int_class = cdrv->int_class;
|
||||
else
|
||||
cdev->private->int_class = IRQIO_CIO;
|
||||
|
||||
ccw_device_set_int_class(cdev);
|
||||
ret = cdrv->probe ? cdrv->probe(cdev) : -ENODEV;
|
||||
|
||||
if (ret) {
|
||||
cdev->drv = NULL;
|
||||
cdev->private->int_class = IRQIO_CIO;
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS] = {
|
|||
/* N P A M L V H */
|
||||
[QETH_DBF_SETUP] = {"qeth_setup",
|
||||
8, 1, 8, 5, &debug_hex_ascii_view, NULL},
|
||||
[QETH_DBF_MSG] = {"qeth_msg",
|
||||
8, 1, 128, 3, &debug_sprintf_view, NULL},
|
||||
[QETH_DBF_MSG] = {"qeth_msg", 8, 1, 11 * sizeof(long), 3,
|
||||
&debug_sprintf_view, NULL},
|
||||
[QETH_DBF_CTRL] = {"qeth_control",
|
||||
8, 1, QETH_DBF_CTRL_LEN, 5, &debug_hex_ascii_view, NULL},
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue