| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 2 |  *	linux/drivers/video/pmag-ba-fb.c | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 3 |  * | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 4 |  *	PMAG-BA TURBOchannel Color Frame Buffer (CFB) card support, | 
 | 5 |  *	derived from: | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 6 |  *	"HP300 Topcat framebuffer support (derived from macfb of all things) | 
 | 7 |  *	Phil Blundell <philb@gnu.org> 1998", the original code can be | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 8 |  *	found in the file hpfb.c in the same directory. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 9 |  * | 
 | 10 |  *	Based on digital document: | 
 | 11 |  * 	"PMAG-BA TURBOchannel Color Frame Buffer | 
 | 12 |  *	 Functional Specification", Revision 1.2, August 27, 1990 | 
 | 13 |  * | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 14 |  *	DECstation related code Copyright (C) 1999, 2000, 2001 by | 
 | 15 |  *	Michael Engel <engel@unix-ag.org>, | 
 | 16 |  *	Karsten Merker <merker@linuxtag.org> and | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 17 |  *	Harald Koerfgen. | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 18 |  *	Copyright (c) 2005, 2006  Maciej W. Rozycki | 
 | 19 |  *	Copyright (c) 2005  James Simmons | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 20 |  * | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 21 |  *	This file is subject to the terms and conditions of the GNU General | 
 | 22 |  *	Public License.  See the file COPYING in the main directory of this | 
 | 23 |  *	archive for more details. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 24 |  */ | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 25 |  | 
 | 26 | #include <linux/compiler.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 27 | #include <linux/errno.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 28 | #include <linux/fb.h> | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 29 | #include <linux/init.h> | 
 | 30 | #include <linux/kernel.h> | 
 | 31 | #include <linux/module.h> | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 32 | #include <linux/tc.h> | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 33 | #include <linux/types.h> | 
 | 34 |  | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 35 | #include <asm/io.h> | 
 | 36 | #include <asm/system.h> | 
 | 37 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 38 | #include <video/pmag-ba-fb.h> | 
 | 39 |  | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 40 |  | 
 | 41 | struct pmagbafb_par { | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 42 | 	volatile void __iomem *mmio; | 
 | 43 | 	volatile u32 __iomem *dac; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 44 | }; | 
 | 45 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 46 |  | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 47 | static struct fb_var_screeninfo pmagbafb_defined __initdata = { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 48 | 	.xres		= 1024, | 
 | 49 | 	.yres		= 864, | 
 | 50 | 	.xres_virtual	= 1024, | 
 | 51 | 	.yres_virtual	= 864, | 
 | 52 | 	.bits_per_pixel	= 8, | 
 | 53 | 	.red.length	= 8, | 
 | 54 | 	.green.length	= 8, | 
 | 55 | 	.blue.length	= 8, | 
 | 56 | 	.activate	= FB_ACTIVATE_NOW, | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 57 | 	.height		= -1, | 
 | 58 | 	.width		= -1, | 
 | 59 | 	.accel_flags	= FB_ACCEL_NONE, | 
 | 60 | 	.pixclock	= 14452, | 
 | 61 | 	.left_margin	= 116, | 
 | 62 | 	.right_margin	= 12, | 
 | 63 | 	.upper_margin	= 34, | 
 | 64 | 	.lower_margin	= 12, | 
 | 65 | 	.hsync_len	= 128, | 
 | 66 | 	.vsync_len	= 3, | 
 | 67 | 	.sync		= FB_SYNC_ON_GREEN, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 68 | 	.vmode		= FB_VMODE_NONINTERLACED, | 
 | 69 | }; | 
 | 70 |  | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 71 | static struct fb_fix_screeninfo pmagbafb_fix __initdata = { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 72 | 	.id		= "PMAG-BA", | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 73 | 	.smem_len	= (1024 * 1024), | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 74 | 	.type		= FB_TYPE_PACKED_PIXELS, | 
 | 75 | 	.visual		= FB_VISUAL_PSEUDOCOLOR, | 
 | 76 | 	.line_length	= 1024, | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 77 | 	.mmio_len	= PMAG_BA_SIZE - PMAG_BA_BT459, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 78 | }; | 
 | 79 |  | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 80 |  | 
 | 81 | static inline void dac_write(struct pmagbafb_par *par, unsigned int reg, u8 v) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 82 | { | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 83 | 	writeb(v, par->dac + reg / 4); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 84 | } | 
 | 85 |  | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 86 | static inline u8 dac_read(struct pmagbafb_par *par, unsigned int reg) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 87 | { | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 88 | 	return readb(par->dac + reg / 4); | 
 | 89 | } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 90 |  | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 91 |  | 
 | 92 | /* | 
 | 93 |  * Set the palette. | 
 | 94 |  */ | 
 | 95 | static int pmagbafb_setcolreg(unsigned int regno, unsigned int red, | 
 | 96 | 			      unsigned int green, unsigned int blue, | 
 | 97 | 			      unsigned int transp, struct fb_info *info) | 
 | 98 | { | 
 | 99 | 	struct pmagbafb_par *par = info->par; | 
 | 100 |  | 
 | 101 | 	BUG_ON(regno >= info->cmap.len); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 102 |  | 
 | 103 | 	red   >>= 8;	/* The cmap fields are 16 bits    */ | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 104 | 	green >>= 8;	/* wide, but the hardware colormap */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 105 | 	blue  >>= 8;	/* registers are only 8 bits wide */ | 
 | 106 |  | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 107 | 	mb(); | 
 | 108 | 	dac_write(par, BT459_ADDR_LO, regno); | 
 | 109 | 	dac_write(par, BT459_ADDR_HI, 0x00); | 
 | 110 | 	wmb(); | 
 | 111 | 	dac_write(par, BT459_CMAP, red); | 
 | 112 | 	wmb(); | 
 | 113 | 	dac_write(par, BT459_CMAP, green); | 
 | 114 | 	wmb(); | 
 | 115 | 	dac_write(par, BT459_CMAP, blue); | 
 | 116 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 117 | 	return 0; | 
 | 118 | } | 
 | 119 |  | 
 | 120 | static struct fb_ops pmagbafb_ops = { | 
 | 121 | 	.owner		= THIS_MODULE, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 122 | 	.fb_setcolreg	= pmagbafb_setcolreg, | 
 | 123 | 	.fb_fillrect	= cfb_fillrect, | 
 | 124 | 	.fb_copyarea	= cfb_copyarea, | 
 | 125 | 	.fb_imageblit	= cfb_imageblit, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 126 | }; | 
 | 127 |  | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 128 |  | 
 | 129 | /* | 
 | 130 |  * Turn the hardware cursor off. | 
 | 131 |  */ | 
 | 132 | static void __init pmagbafb_erase_cursor(struct fb_info *info) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 133 | { | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 134 | 	struct pmagbafb_par *par = info->par; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 135 |  | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 136 | 	mb(); | 
 | 137 | 	dac_write(par, BT459_ADDR_LO, 0x00); | 
 | 138 | 	dac_write(par, BT459_ADDR_HI, 0x03); | 
 | 139 | 	wmb(); | 
 | 140 | 	dac_write(par, BT459_DATA, 0x00); | 
 | 141 | } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 142 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 143 |  | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 144 | static int __init pmagbafb_probe(struct device *dev) | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 145 | { | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 146 | 	struct tc_dev *tdev = to_tc_dev(dev); | 
 | 147 | 	resource_size_t start, len; | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 148 | 	struct fb_info *info; | 
 | 149 | 	struct pmagbafb_par *par; | 
| Maciej W. Rozycki | 53ee1b5 | 2007-10-16 01:29:30 -0700 | [diff] [blame] | 150 | 	int err; | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 151 |  | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 152 | 	info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev); | 
| Maciej W. Rozycki | 53ee1b5 | 2007-10-16 01:29:30 -0700 | [diff] [blame] | 153 | 	if (!info) { | 
 | 154 | 		printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id); | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 155 | 		return -ENOMEM; | 
| Maciej W. Rozycki | 53ee1b5 | 2007-10-16 01:29:30 -0700 | [diff] [blame] | 156 | 	} | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 157 |  | 
 | 158 | 	par = info->par; | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 159 | 	dev_set_drvdata(dev, info); | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 160 |  | 
| Maciej W. Rozycki | 53ee1b5 | 2007-10-16 01:29:30 -0700 | [diff] [blame] | 161 | 	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { | 
 | 162 | 		printk(KERN_ERR "%s: Cannot allocate color map\n", | 
 | 163 | 		       dev->bus_id); | 
 | 164 | 		err = -ENOMEM; | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 165 | 		goto err_alloc; | 
| Maciej W. Rozycki | 53ee1b5 | 2007-10-16 01:29:30 -0700 | [diff] [blame] | 166 | 	} | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 167 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 168 | 	info->fbops = &pmagbafb_ops; | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 169 | 	info->fix = pmagbafb_fix; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 170 | 	info->var = pmagbafb_defined; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 171 | 	info->flags = FBINFO_DEFAULT; | 
 | 172 |  | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 173 | 	/* Request the I/O MEM resource.  */ | 
 | 174 | 	start = tdev->resource.start; | 
 | 175 | 	len = tdev->resource.end - start + 1; | 
| Maciej W. Rozycki | 53ee1b5 | 2007-10-16 01:29:30 -0700 | [diff] [blame] | 176 | 	if (!request_mem_region(start, len, dev->bus_id)) { | 
 | 177 | 		printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id); | 
 | 178 | 		err = -EBUSY; | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 179 | 		goto err_cmap; | 
| Maciej W. Rozycki | 53ee1b5 | 2007-10-16 01:29:30 -0700 | [diff] [blame] | 180 | 	} | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 181 |  | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 182 | 	/* MMIO mapping setup.  */ | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 183 | 	info->fix.mmio_start = start; | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 184 | 	par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); | 
| Maciej W. Rozycki | 53ee1b5 | 2007-10-16 01:29:30 -0700 | [diff] [blame] | 185 | 	if (!par->mmio) { | 
 | 186 | 		printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id); | 
 | 187 | 		err = -ENOMEM; | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 188 | 		goto err_resource; | 
| Maciej W. Rozycki | 53ee1b5 | 2007-10-16 01:29:30 -0700 | [diff] [blame] | 189 | 	} | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 190 | 	par->dac = par->mmio + PMAG_BA_BT459; | 
 | 191 |  | 
 | 192 | 	/* Frame buffer mapping setup.  */ | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 193 | 	info->fix.smem_start = start + PMAG_BA_FBMEM; | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 194 | 	info->screen_base = ioremap_nocache(info->fix.smem_start, | 
 | 195 | 					    info->fix.smem_len); | 
| Maciej W. Rozycki | 53ee1b5 | 2007-10-16 01:29:30 -0700 | [diff] [blame] | 196 | 	if (!info->screen_base) { | 
 | 197 | 		printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id); | 
 | 198 | 		err = -ENOMEM; | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 199 | 		goto err_mmio_map; | 
| Maciej W. Rozycki | 53ee1b5 | 2007-10-16 01:29:30 -0700 | [diff] [blame] | 200 | 	} | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 201 | 	info->screen_size = info->fix.smem_len; | 
 | 202 |  | 
 | 203 | 	pmagbafb_erase_cursor(info); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 204 |  | 
| Maciej W. Rozycki | 53ee1b5 | 2007-10-16 01:29:30 -0700 | [diff] [blame] | 205 | 	err = register_framebuffer(info); | 
 | 206 | 	if (err < 0) { | 
 | 207 | 		printk(KERN_ERR "%s: Cannot register framebuffer\n", | 
 | 208 | 		       dev->bus_id); | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 209 | 		goto err_smem_map; | 
| Maciej W. Rozycki | 53ee1b5 | 2007-10-16 01:29:30 -0700 | [diff] [blame] | 210 | 	} | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 211 |  | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 212 | 	get_device(dev); | 
 | 213 |  | 
 | 214 | 	pr_info("fb%d: %s frame buffer device at %s\n", | 
 | 215 | 		info->node, info->fix.id, dev->bus_id); | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 216 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 217 | 	return 0; | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 218 |  | 
 | 219 |  | 
 | 220 | err_smem_map: | 
 | 221 | 	iounmap(info->screen_base); | 
 | 222 |  | 
 | 223 | err_mmio_map: | 
 | 224 | 	iounmap(par->mmio); | 
 | 225 |  | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 226 | err_resource: | 
 | 227 | 	release_mem_region(start, len); | 
 | 228 |  | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 229 | err_cmap: | 
 | 230 | 	fb_dealloc_cmap(&info->cmap); | 
 | 231 |  | 
 | 232 | err_alloc: | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 233 | 	framebuffer_release(info); | 
| Maciej W. Rozycki | 53ee1b5 | 2007-10-16 01:29:30 -0700 | [diff] [blame] | 234 | 	return err; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 235 | } | 
 | 236 |  | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 237 | static int __exit pmagbafb_remove(struct device *dev) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 238 | { | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 239 | 	struct tc_dev *tdev = to_tc_dev(dev); | 
 | 240 | 	struct fb_info *info = dev_get_drvdata(dev); | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 241 | 	struct pmagbafb_par *par = info->par; | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 242 | 	resource_size_t start, len; | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 243 |  | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 244 | 	put_device(dev); | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 245 | 	unregister_framebuffer(info); | 
 | 246 | 	iounmap(info->screen_base); | 
 | 247 | 	iounmap(par->mmio); | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 248 | 	start = tdev->resource.start; | 
 | 249 | 	len = tdev->resource.end - start + 1; | 
 | 250 | 	release_mem_region(start, len); | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 251 | 	fb_dealloc_cmap(&info->cmap); | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 252 | 	framebuffer_release(info); | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 253 | 	return 0; | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 254 | } | 
 | 255 |  | 
 | 256 |  | 
 | 257 | /* | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 258 |  * Initialize the framebuffer. | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 259 |  */ | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 260 | static const struct tc_device_id pmagbafb_tc_table[] = { | 
 | 261 | 	{ "DEC     ", "PMAG-BA " }, | 
 | 262 | 	{ } | 
 | 263 | }; | 
 | 264 | MODULE_DEVICE_TABLE(tc, pmagbafb_tc_table); | 
 | 265 |  | 
 | 266 | static struct tc_driver pmagbafb_driver = { | 
 | 267 | 	.id_table	= pmagbafb_tc_table, | 
 | 268 | 	.driver		= { | 
 | 269 | 		.name	= "pmagbafb", | 
 | 270 | 		.bus	= &tc_bus_type, | 
 | 271 | 		.probe	= pmagbafb_probe, | 
 | 272 | 		.remove	= __exit_p(pmagbafb_remove), | 
 | 273 | 	}, | 
 | 274 | }; | 
 | 275 |  | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 276 | static int __init pmagbafb_init(void) | 
 | 277 | { | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 278 | #ifndef MODULE | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 279 | 	if (fb_get_options("pmagbafb", NULL)) | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 280 | 		return -ENXIO; | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 281 | #endif | 
 | 282 | 	return tc_register_driver(&pmagbafb_driver); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 283 | } | 
 | 284 |  | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 285 | static void __exit pmagbafb_exit(void) | 
 | 286 | { | 
| Maciej W. Rozycki | 335dc50 | 2007-02-05 16:28:28 -0800 | [diff] [blame] | 287 | 	tc_unregister_driver(&pmagbafb_driver); | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 288 | } | 
 | 289 |  | 
 | 290 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 291 | module_init(pmagbafb_init); | 
| Ralf Baechle | af690a9 | 2005-09-03 15:56:09 -0700 | [diff] [blame] | 292 | module_exit(pmagbafb_exit); | 
 | 293 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 294 | MODULE_LICENSE("GPL"); |