/* * 3215 console initialization code called from console_init(). */ static int __init con3215_init(void) { struct ccw_device *cdev; struct raw3215_info *raw; struct raw3215_req *req; int i; /* Check if 3215 is to be the console */ if (!CONSOLE_IS_3215) return -ENODEV; /* Set the console mode for VM */ if (MACHINE_IS_VM) { cpcmd("TERM CONMODE 3215", NULL, 0, NULL); cpcmd("TERM AUTOCR OFF", NULL, 0, NULL); } /* allocate 3215 request structures */ raw3215_freelist = NULL; spin_lock_init(&raw3215_freelist_lock); for (i = 0; i < NR_3215_REQ; i++) { req = kzalloc(sizeof(struct raw3215_req), GFP_KERNEL | GFP_DMA); if (!req) return -ENOMEM; req->next = raw3215_freelist; raw3215_freelist = req; } cdev = ccw_device_create_console(&raw3215_ccw_driver); if (IS_ERR(cdev)) return -ENODEV; raw3215[0] = raw = raw3215_alloc_info(); raw->cdev = cdev; dev_set_drvdata(&cdev->dev, raw); 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) { raw3215_free_info(raw); raw3215[0] = NULL; return -ENODEV; } atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb); register_reboot_notifier(&on_reboot_nb); register_console(&con3215); return 0; }
static int raw3215_probe (struct ccw_device *cdev) { struct raw3215_info *raw; int line; /* Console is special. */ if (raw3215[0] && (raw3215[0] == dev_get_drvdata(&cdev->dev))) return 0; raw = raw3215_alloc_info(); if (raw == NULL) return -ENOMEM; raw->cdev = cdev; dev_set_drvdata(&cdev->dev, raw); cdev->handler = raw3215_irq; spin_lock(&raw3215_device_lock); for (line = 0; line < NR_3215; line++) { if (!raw3215[line]) { raw3215[line] = raw; break; } } spin_unlock(&raw3215_device_lock); if (line == NR_3215) { raw3215_free_info(raw); return -ENODEV; } return 0; }
static void raw3215_remove (struct ccw_device *cdev) { struct raw3215_info *raw; unsigned int line; ccw_device_set_offline(cdev); raw = dev_get_drvdata(&cdev->dev); if (raw) { spin_lock(&raw3215_device_lock); for (line = 0; line < NR_3215; line++) if (raw3215[line] == raw) break; raw3215[line] = NULL; spin_unlock(&raw3215_device_lock); dev_set_drvdata(&cdev->dev, NULL); raw3215_free_info(raw); } }