1310599Smmel/* 2310599Smmel * Derived from drm_pci.c 3310599Smmel * 4310599Smmel * Copyright 2003 Jos�� Fonseca. 5310599Smmel * Copyright 2003 Leif Delgass. 6310599Smmel * Copyright (c) 2009, Code Aurora Forum. 7310599Smmel * All Rights Reserved. 8310599Smmel * 9310599Smmel * Permission is hereby granted, free of charge, to any person obtaining a 10310599Smmel * copy of this software and associated documentation files (the "Software"), 11310599Smmel * to deal in the Software without restriction, including without limitation 12310599Smmel * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13310599Smmel * and/or sell copies of the Software, and to permit persons to whom the 14310599Smmel * Software is furnished to do so, subject to the following conditions: 15310599Smmel * 16310599Smmel * The above copyright notice and this permission notice (including the next 17310599Smmel * paragraph) shall be included in all copies or substantial portions of the 18310599Smmel * Software. 19310599Smmel * 20310599Smmel * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21310599Smmel * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22310599Smmel * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23310599Smmel * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 24310599Smmel * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25310599Smmel * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26310599Smmel */ 27310599Smmel#include <sys/cdefs.h> 28310599Smmel__FBSDID("$FreeBSD: stable/11/sys/dev/drm2/drm_platform.c 317011 2017-04-16 08:07:38Z mmel $"); 29310599Smmel 30310599Smmel#include <dev/drm2/drmP.h> 31310599Smmel 32310599Smmelstatic void drm_platform_free_irq(struct drm_device *dev) 33310599Smmel{ 34310599Smmel if (dev->irqr == NULL) 35310599Smmel return; 36310599Smmel 37310599Smmel bus_release_resource(dev->dev, SYS_RES_IRQ, 38310599Smmel dev->irqrid, dev->irqr); 39310599Smmel 40310599Smmel dev->irqr = NULL; 41310599Smmel dev->irq = 0; 42310599Smmel} 43310599Smmel 44310599Smmelstatic const char *drm_platform_get_name(struct drm_device *dev) 45310599Smmel{ 46310599Smmel return dev->driver->name; 47310599Smmel} 48310599Smmel 49310599Smmelstatic int drm_platform_set_busid(struct drm_device *dev, struct drm_master *master) 50310599Smmel{ 51310599Smmel int len, ret, id; 52310599Smmel 53310599Smmel master->unique_len = 13 + strlen(dev->driver->name); 54310599Smmel master->unique_size = master->unique_len; 55310599Smmel master->unique = malloc(master->unique_len + 1, DRM_MEM_DRIVER, M_NOWAIT); 56310599Smmel 57310599Smmel if (master->unique == NULL) 58310599Smmel return -ENOMEM; 59310599Smmel 60310599Smmel id = 0; // XXX dev->driver->id; 61310599Smmel 62310599Smmel /* if only a single instance of the platform device, id will be 63310599Smmel * set to -1.. use 0 instead to avoid a funny looking bus-id: 64310599Smmel */ 65310599Smmel if (id == -1) 66310599Smmel id = 0; 67310599Smmel 68310599Smmel len = snprintf(master->unique, master->unique_len, 69310599Smmel "platform:%s:%02d", dev->driver->name, id); 70310599Smmel 71310599Smmel if (len > master->unique_len) { 72310599Smmel DRM_ERROR("Unique buffer overflowed\n"); 73310599Smmel ret = -EINVAL; 74310599Smmel goto err; 75310599Smmel } 76310599Smmel 77310599Smmel return 0; 78310599Smmelerr: 79310599Smmel return ret; 80310599Smmel} 81310599Smmel 82310599Smmelstatic int drm_platform_get_irq(struct drm_device *dev) 83310599Smmel{ 84310599Smmel if (dev->irqr) 85310599Smmel return (dev->irq); 86310599Smmel 87310599Smmel dev->irqr = bus_alloc_resource_any(dev->dev, SYS_RES_IRQ, 88310599Smmel &dev->irqrid, RF_SHAREABLE); 89310599Smmel if (!dev->irqr) { 90310599Smmel dev_err(dev->dev, "Failed to allocate IRQ\n"); 91310599Smmel return (0); 92310599Smmel } 93310599Smmel 94310599Smmel dev->irq = (int) rman_get_start(dev->irqr); 95310599Smmel 96310599Smmel return (dev->irq); 97310599Smmel} 98310599Smmel 99310599Smmelstatic struct drm_bus drm_platform_bus = { 100310599Smmel .bus_type = DRIVER_BUS_PLATFORM, 101310599Smmel .get_irq = drm_platform_get_irq, 102310599Smmel .free_irq = drm_platform_free_irq, 103310599Smmel .get_name = drm_platform_get_name, 104310599Smmel .set_busid = drm_platform_set_busid, 105310599Smmel}; 106310599Smmel 107310599Smmel/** 108310599Smmel * Register. 109310599Smmel * 110310599Smmel * \param platdev - Platform device struture 111310599Smmel * \return zero on success or a negative number on failure. 112310599Smmel * 113310599Smmel * Attempt to gets inter module "drm" information. If we are first 114310599Smmel * then register the character device and inter module information. 115310599Smmel * Try and register, if we fail to register, backout previous work. 116310599Smmel */ 117310599Smmel 118310599Smmelint drm_get_platform_dev(device_t kdev, struct drm_device *dev, 119310599Smmel struct drm_driver *driver) 120310599Smmel{ 121310599Smmel int ret; 122310599Smmel 123310599Smmel DRM_DEBUG("\n"); 124310599Smmel 125310599Smmel driver->bus = &drm_platform_bus; 126310599Smmel 127310599Smmel dev->dev = kdev; 128310599Smmel 129310599Smmel sx_xlock(&drm_global_mutex); 130310599Smmel 131310599Smmel ret = drm_fill_in_dev(dev, driver); 132310599Smmel 133310599Smmel if (ret) { 134310599Smmel printf("DRM: Fill_in_dev failed.\n"); 135310599Smmel goto err_g1; 136310599Smmel } 137310599Smmel 138310599Smmel if (drm_core_check_feature(dev, DRIVER_MODESET)) { 139310599Smmel ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); 140310599Smmel if (ret) 141310599Smmel goto err_g1; 142310599Smmel } 143310599Smmel 144310599Smmel ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); 145310599Smmel if (ret) 146310599Smmel goto err_g2; 147310599Smmel 148310599Smmel if (dev->driver->load) { 149310599Smmel ret = dev->driver->load(dev, 0); 150310599Smmel if (ret) 151310599Smmel goto err_g3; 152310599Smmel } 153310599Smmel 154310599Smmel /* setup the grouping for the legacy output */ 155310599Smmel if (drm_core_check_feature(dev, DRIVER_MODESET)) { 156310599Smmel ret = drm_mode_group_init_legacy_group(dev, 157310599Smmel &dev->primary->mode_group); 158310599Smmel if (ret) 159310599Smmel goto err_g3; 160310599Smmel } 161310599Smmel 162310599Smmel#ifdef FREEBSD_NOTYET 163310599Smmel list_add_tail(&dev->driver_item, &driver->device_list); 164310599Smmel#endif /* FREEBSD_NOTYET */ 165310599Smmel 166310599Smmel sx_xunlock(&drm_global_mutex); 167310599Smmel 168310599Smmel DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", 169310599Smmel driver->name, driver->major, driver->minor, driver->patchlevel, 170310599Smmel driver->date, dev->primary->index); 171310599Smmel 172310599Smmel return 0; 173310599Smmel 174310599Smmelerr_g3: 175310599Smmel drm_put_minor(&dev->primary); 176310599Smmelerr_g2: 177310599Smmel if (drm_core_check_feature(dev, DRIVER_MODESET)) 178310599Smmel drm_put_minor(&dev->control); 179310599Smmelerr_g1: 180310599Smmel sx_xunlock(&drm_global_mutex); 181310599Smmel return ret; 182310599Smmel} 183310599SmmelEXPORT_SYMBOL(drm_get_platform_dev); 184