radeon_backlight.c revision 6c34bc2976b30dc8b56392c020e25bae1f363cab
15474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann/* 25474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann * Backlight code for ATI Radeon based graphic cards 35474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann * 45474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann * Copyright (c) 2000 Ani Joshi <ajoshi@kernel.crashing.org> 55474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann * Copyright (c) 2003 Benjamin Herrenschmidt <benh@kernel.crashing.org> 65474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann * Copyright (c) 2006 Michael Hanselmann <linux-kernel@hansmi.ch> 75474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann * 85474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann * This program is free software; you can redistribute it and/or modify 95474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann * it under the terms of the GNU General Public License version 2 as 105474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann * published by the Free Software Foundation. 115474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann */ 125474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 135474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann#include "radeonfb.h" 145474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann#include <linux/backlight.h> 155474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 165474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann#ifdef CONFIG_PMAC_BACKLIGHT 175474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann#include <asm/backlight.h> 185474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann#endif 195474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 205474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann#define MAX_RADEON_LEVEL 0xFF 215474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 225474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmannstruct radeon_bl_privdata { 235474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann struct radeonfb_info *rinfo; 245474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann uint8_t negative; 255474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann}; 265474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 275474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmannstatic int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata, 285474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann int level) 295474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann{ 305474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann int rlevel; 315474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 325474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann /* Get and convert the value */ 3337ce69a57ff217a4ca0871e9ee5aa58c052b7d86Richard Purdie /* No locking of bl_curve since we read a single value */ 345474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rlevel = pdata->rinfo->info->bl_curve[level] * 355474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL; 365474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 375474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann if (rlevel < 0) 385474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rlevel = 0; 395474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann else if (rlevel > MAX_RADEON_LEVEL) 405474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rlevel = MAX_RADEON_LEVEL; 415474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 42cab267c65f44337974e4f1eae490b21dce0e9811Michael Hanselmann if (pdata->negative) 43cab267c65f44337974e4f1eae490b21dce0e9811Michael Hanselmann rlevel = MAX_RADEON_LEVEL - rlevel; 44cab267c65f44337974e4f1eae490b21dce0e9811Michael Hanselmann 455474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann return rlevel; 465474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann} 475474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 485474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmannstatic int radeon_bl_update_status(struct backlight_device *bd) 495474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann{ 50655bfd7aebb12481ab9275284d9500bee5ba3e70Richard Purdie struct radeon_bl_privdata *pdata = bl_get_data(bd); 515474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann struct radeonfb_info *rinfo = pdata->rinfo; 525474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann u32 lvds_gen_cntl, tmpPixclksCntl; 535474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann int level; 545474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 555474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann if (rinfo->mon1_type != MT_LCD) 565474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann return 0; 575474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 585474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann /* We turn off the LCD completely instead of just dimming the 595474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann * backlight. This provides some greater power saving and the display 605474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann * is useless without backlight anyway. 615474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann */ 62599a52d12629394236d785615808845823875868Richard Purdie if (bd->props.power != FB_BLANK_UNBLANK || 63599a52d12629394236d785615808845823875868Richard Purdie bd->props.fb_blank != FB_BLANK_UNBLANK) 645474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann level = 0; 655474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann else 66599a52d12629394236d785615808845823875868Richard Purdie level = bd->props.brightness; 675474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 685474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann del_timer_sync(&rinfo->lvds_timer); 696c34bc2976b30dc8b56392c020e25bae1f363cabLinus Torvalds radeon_engine_idle(); 705474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 715474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl = INREG(LVDS_GEN_CNTL); 725474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann if (level > 0) { 735474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl &= ~LVDS_DISPLAY_DIS; 745474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann if (!(lvds_gen_cntl & LVDS_BLON) || !(lvds_gen_cntl & LVDS_ON)) { 755474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_DIGON); 765474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl |= LVDS_BLON | LVDS_EN; 775474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); 785474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK; 795474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl |= 805474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann (radeon_bl_get_level_brightness(pdata, level) << 815474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann LVDS_BL_MOD_LEVEL_SHIFT); 825474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl |= LVDS_ON; 835474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_BL_MOD_EN); 845474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rinfo->pending_lvds_gen_cntl = lvds_gen_cntl; 855474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann mod_timer(&rinfo->lvds_timer, 865474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay)); 875474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann } else { 885474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK; 895474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl |= 905474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann (radeon_bl_get_level_brightness(pdata, level) << 915474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann LVDS_BL_MOD_LEVEL_SHIFT); 925474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); 935474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann } 945474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; 955474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rinfo->init_state.lvds_gen_cntl |= rinfo->pending_lvds_gen_cntl 965474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann & LVDS_STATE_MASK; 975474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann } else { 985474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann /* Asic bug, when turning off LVDS_ON, we have to make sure 995474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off 1005474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann */ 1015474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann tmpPixclksCntl = INPLL(PIXCLKS_CNTL); 1025474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann if (rinfo->is_mobility || rinfo->is_IGP) 1035474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb); 1045474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl &= ~(LVDS_BL_MOD_LEVEL_MASK | LVDS_BL_MOD_EN); 1055474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl |= (radeon_bl_get_level_brightness(pdata, 0) << 1065474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann LVDS_BL_MOD_LEVEL_SHIFT); 1075474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl |= LVDS_DISPLAY_DIS; 1085474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); 1095474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann udelay(100); 1105474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN); 1115474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl); 1125474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann lvds_gen_cntl &= ~(LVDS_DIGON); 1135474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rinfo->pending_lvds_gen_cntl = lvds_gen_cntl; 1145474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann mod_timer(&rinfo->lvds_timer, 1155474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann jiffies + msecs_to_jiffies(rinfo->panel_info.pwr_delay)); 1165474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann if (rinfo->is_mobility || rinfo->is_IGP) 1175474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann OUTPLL(PIXCLKS_CNTL, tmpPixclksCntl); 1185474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann } 1195474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; 1205474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK); 1215474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 1225474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann return 0; 1235474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann} 1245474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 1255474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmannstatic int radeon_bl_get_brightness(struct backlight_device *bd) 1265474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann{ 127599a52d12629394236d785615808845823875868Richard Purdie return bd->props.brightness; 1285474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann} 1295474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 130599a52d12629394236d785615808845823875868Richard Purdiestatic struct backlight_ops radeon_bl_data = { 1315474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann .get_brightness = radeon_bl_get_brightness, 1325474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann .update_status = radeon_bl_update_status, 1335474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann}; 1345474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 1355474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmannvoid radeonfb_bl_init(struct radeonfb_info *rinfo) 1365474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann{ 1375474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann struct backlight_device *bd; 1385474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann struct radeon_bl_privdata *pdata; 1395474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann char name[12]; 1405474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 1415474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann if (rinfo->mon1_type != MT_LCD) 1425474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann return; 1435474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 1445474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann#ifdef CONFIG_PMAC_BACKLIGHT 1455474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann if (!pmac_has_backlight_type("ati") && 1465474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann !pmac_has_backlight_type("mnca")) 1475474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann return; 1485474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann#endif 1495474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 1505474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann pdata = kmalloc(sizeof(struct radeon_bl_privdata), GFP_KERNEL); 1515474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann if (!pdata) { 1525474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann printk("radeonfb: Memory allocation failed\n"); 1535474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann goto error; 1545474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann } 1555474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 1565474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node); 1575474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 158a8274d57afb83e4954ddcb3f8b7dd1c03a379bd4James Simmons bd = backlight_device_register(name, rinfo->info->dev, pdata, &radeon_bl_data); 1595474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann if (IS_ERR(bd)) { 1605474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rinfo->info->bl_dev = NULL; 1615474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann printk("radeonfb: Backlight registration failed\n"); 1625474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann goto error; 1635474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann } 1645474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 1655474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann pdata->rinfo = rinfo; 1665474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 1675474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann /* Pardon me for that hack... maybe some day we can figure out in what 1685474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann * direction backlight should work on a given panel? 1695474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann */ 1705474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann pdata->negative = 1715474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann (rinfo->family != CHIP_FAMILY_RV200 && 1725474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rinfo->family != CHIP_FAMILY_RV250 && 1735474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rinfo->family != CHIP_FAMILY_RV280 && 1745474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rinfo->family != CHIP_FAMILY_RV350); 1755474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 1765474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann#ifdef CONFIG_PMAC_BACKLIGHT 1775474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann pdata->negative = pdata->negative || 1785474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann machine_is_compatible("PowerBook4,3") || 1795474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann machine_is_compatible("PowerBook6,3") || 1805474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann machine_is_compatible("PowerBook6,5"); 1815474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann#endif 1825474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 1835474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rinfo->info->bl_dev = bd; 1845474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann fb_bl_default_curve(rinfo->info, 0, 1855474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL, 1865474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL); 1875474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 188599a52d12629394236d785615808845823875868Richard Purdie bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 189599a52d12629394236d785615808845823875868Richard Purdie bd->props.brightness = bd->props.max_brightness; 190599a52d12629394236d785615808845823875868Richard Purdie bd->props.power = FB_BLANK_UNBLANK; 19128ee086d5b36aab2931f6740e409bb0fb6c65e5fRichard Purdie backlight_update_status(bd); 1925474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 1935474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann printk("radeonfb: Backlight initialized (%s)\n", name); 1945474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 1955474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann return; 1965474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 1975474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmannerror: 1985474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann kfree(pdata); 1995474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann return; 2005474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann} 2015474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 2025474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmannvoid radeonfb_bl_exit(struct radeonfb_info *rinfo) 2035474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann{ 20437ce69a57ff217a4ca0871e9ee5aa58c052b7d86Richard Purdie struct backlight_device *bd = rinfo->info->bl_dev; 2055474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 20637ce69a57ff217a4ca0871e9ee5aa58c052b7d86Richard Purdie if (bd) { 2075474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann struct radeon_bl_privdata *pdata; 2085474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 209655bfd7aebb12481ab9275284d9500bee5ba3e70Richard Purdie pdata = bl_get_data(bd); 21037ce69a57ff217a4ca0871e9ee5aa58c052b7d86Richard Purdie backlight_device_unregister(bd); 2115474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann kfree(pdata); 2125474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann rinfo->info->bl_dev = NULL; 2135474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann 2145474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann printk("radeonfb: Backlight unloaded\n"); 2155474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann } 2165474c120aafe78ca54bf272f7a01107c42da2b21Michael Hanselmann} 217