blob: bde47e9080cd9a131dc76563e42d01e273bab990 [file] [log] [blame]
Mark Allyn433e63c2010-02-05 10:53:18 -08001/*
2 * rar_register.c - An Intel Restricted Access Region register driver
3 *
4 * Copyright(c) 2009 Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 *
21 * -------------------------------------------------------------------
22 * 20091204 Mark Allyn <mark.a.allyn@intel.com>
23 * Ossama Othman <ossama.othman@intel.com>
24 * Cleanup per feedback from Alan Cox and Arjan Van De Ven
25 *
26 * 20090806 Ossama Othman <ossama.othman@intel.com>
27 * Return zero high address if upper 22 bits is zero.
28 * Cleaned up checkpatch errors.
29 * Clarified that driver is dealing with bus addresses.
30 *
31 * 20090702 Ossama Othman <ossama.othman@intel.com>
32 * Removed unnecessary include directives
33 * Cleaned up spinlocks.
34 * Cleaned up logging.
35 * Improved invalid parameter checks.
36 * Fixed and simplified RAR address retrieval and RAR locking
37 * code.
38 *
39 * 20090626 Mark Allyn <mark.a.allyn@intel.com>
40 * Initial publish
41 */
42
Mark Allyn433e63c2010-02-05 10:53:18 -080043#include <linux/module.h>
44#include <linux/pci.h>
45#include <linux/spinlock.h>
46#include <linux/device.h>
47#include <linux/kernel.h>
Alan Coxc715a382010-06-18 14:05:52 +010048#include <linux/rar_register.h>
Alan Cox542385e2009-08-06 20:44:18 +010049
50/* === Lincroft Message Bus Interface === */
Alan Cox375d65d2010-05-04 20:40:12 +010051#define LNC_MCR_OFFSET 0xD0 /* Message Control Register */
52#define LNC_MDR_OFFSET 0xD4 /* Message Data Register */
Alan Cox542385e2009-08-06 20:44:18 +010053
54/* Message Opcodes */
Alan Cox375d65d2010-05-04 20:40:12 +010055#define LNC_MESSAGE_READ_OPCODE 0xD0
Alan Cox542385e2009-08-06 20:44:18 +010056#define LNC_MESSAGE_WRITE_OPCODE 0xE0
57
58/* Message Write Byte Enables */
Alan Cox375d65d2010-05-04 20:40:12 +010059#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF
Alan Cox542385e2009-08-06 20:44:18 +010060
61/* B-unit Port */
Alan Cox375d65d2010-05-04 20:40:12 +010062#define LNC_BUNIT_PORT 0x3
Alan Cox542385e2009-08-06 20:44:18 +010063
64/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */
Alan Cox375d65d2010-05-04 20:40:12 +010065#define LNC_BRAR0L 0x10
66#define LNC_BRAR0H 0x11
67#define LNC_BRAR1L 0x12
68#define LNC_BRAR1H 0x13
Alan Cox542385e2009-08-06 20:44:18 +010069/* Reserved for SeP */
Alan Cox375d65d2010-05-04 20:40:12 +010070#define LNC_BRAR2L 0x14
71#define LNC_BRAR2H 0x15
Alan Cox542385e2009-08-06 20:44:18 +010072
73/* Moorestown supports three restricted access regions. */
74#define MRST_NUM_RAR 3
75
Mark Allyn433e63c2010-02-05 10:53:18 -080076/* RAR Bus Address Range */
Alan Cox375d65d2010-05-04 20:40:12 +010077struct rar_addr {
Mark Allyn433e63c2010-02-05 10:53:18 -080078 dma_addr_t low;
79 dma_addr_t high;
Alan Cox542385e2009-08-06 20:44:18 +010080};
81
Alan Cox375d65d2010-05-04 20:40:12 +010082/*
83 * We create one of these for each RAR
84 */
Mark Allyn433e63c2010-02-05 10:53:18 -080085struct client {
Alan Cox375d65d2010-05-04 20:40:12 +010086 int (*callback)(unsigned long data);
87 unsigned long driver_priv;
88 bool busy;
89};
Alan Cox542385e2009-08-06 20:44:18 +010090
Mark Allyn433e63c2010-02-05 10:53:18 -080091static DEFINE_MUTEX(rar_mutex);
92static DEFINE_MUTEX(lnc_reg_mutex);
Alan Cox542385e2009-08-06 20:44:18 +010093
Alan Cox375d65d2010-05-04 20:40:12 +010094/*
95 * One per RAR device (currently only one device)
96 */
97struct rar_device {
98 struct rar_addr rar_addr[MRST_NUM_RAR];
Mark Allyn433e63c2010-02-05 10:53:18 -080099 struct pci_dev *rar_dev;
100 bool registered;
Alan Cox375d65d2010-05-04 20:40:12 +0100101 bool allocated;
102 struct client client[MRST_NUM_RAR];
Mark Allyn433e63c2010-02-05 10:53:18 -0800103};
104
Alan Cox375d65d2010-05-04 20:40:12 +0100105/* Current platforms have only one rar_device for 3 rar regions */
106static struct rar_device my_rar_device;
Mark Allyn433e63c2010-02-05 10:53:18 -0800107
108/*
Alan Cox375d65d2010-05-04 20:40:12 +0100109 * Abstract out multiple device support. Current platforms only
110 * have a single RAR device.
Mark Allyn433e63c2010-02-05 10:53:18 -0800111 */
Alan Cox375d65d2010-05-04 20:40:12 +0100112
113/**
114 * alloc_rar_device - return a new RAR structure
115 *
116 * Return a new (but not yet ready) RAR device object
117 */
118static struct rar_device *alloc_rar_device(void)
119{
120 if (my_rar_device.allocated)
121 return NULL;
122 my_rar_device.allocated = 1;
123 return &my_rar_device;
124}
125
126/**
127 * free_rar_device - free a RAR object
128 * @rar: the RAR device being freed
129 *
130 * Release a RAR object and any attached resources
131 */
132static void free_rar_device(struct rar_device *rar)
133{
134 pci_dev_put(rar->rar_dev);
135 rar->allocated = 0;
136}
137
138/**
139 * _rar_to_device - return the device handling this RAR
140 * @rar: RAR number
141 * @off: returned offset
142 *
143 * Internal helper for looking up RAR devices. This and alloc are the
144 * two functions that need touching to go to multiple RAR devices.
145 */
146static struct rar_device *_rar_to_device(int rar, int *off)
147{
Ossama Othmana9728c92010-08-24 12:55:14 +0100148 if (rar >= 0 && rar < MRST_NUM_RAR) {
Alan Cox375d65d2010-05-04 20:40:12 +0100149 *off = rar;
150 return &my_rar_device;
151 }
152 return NULL;
153}
154
Alan Cox375d65d2010-05-04 20:40:12 +0100155/**
156 * rar_to_device - return the device handling this RAR
157 * @rar: RAR number
158 * @off: returned offset
159 *
160 * Return the device this RAR maps to if one is present, otherwise
161 * returns NULL. Reports the offset relative to the base of this
162 * RAR device in off.
163 */
164static struct rar_device *rar_to_device(int rar, int *off)
165{
166 struct rar_device *rar_dev = _rar_to_device(rar, off);
167 if (rar_dev == NULL || !rar_dev->registered)
168 return NULL;
169 return rar_dev;
170}
171
172/**
173 * rar_to_client - return the client handling this RAR
174 * @rar: RAR number
175 *
176 * Return the client this RAR maps to if a mapping is known, otherwise
177 * returns NULL.
178 */
179static struct client *rar_to_client(int rar)
180{
181 int idx;
182 struct rar_device *r = _rar_to_device(rar, &idx);
183 if (r != NULL)
184 return &r->client[idx];
185 return NULL;
186}
187
188/**
189 * rar_read_addr - retrieve a RAR mapping
190 * @pdev: PCI device for the RAR
191 * @offset: offset for message
192 * @addr: returned address
193 *
194 * Reads the address of a given RAR register. Returns 0 on success
195 * or an error code on failure.
196 */
197static int rar_read_addr(struct pci_dev *pdev, int offset, dma_addr_t *addr)
Mark Allyn433e63c2010-02-05 10:53:18 -0800198{
Alan Cox542385e2009-08-06 20:44:18 +0100199 /*
Mark Allyn433e63c2010-02-05 10:53:18 -0800200 * ======== The Lincroft Message Bus Interface ========
Alan Cox375d65d2010-05-04 20:40:12 +0100201 * Lincroft registers may be obtained via PCI from
202 * the host bridge using the Lincroft Message Bus
Mark Allyn433e63c2010-02-05 10:53:18 -0800203 * Interface. That message bus interface is generally
204 * comprised of two registers: a control register (MCR, 0xDO)
205 * and a data register (MDR, 0xD4).
206 *
207 * The MCR (message control register) format is the following:
208 * 1. [31:24]: Opcode
209 * 2. [23:16]: Port
210 * 3. [15:8]: Register Offset
211 * 4. [7:4]: Byte Enables (use 0xF to set all of these bits
212 * to 1)
213 * 5. [3:0]: reserved
214 *
215 * Read (0xD0) and write (0xE0) opcodes are written to the
216 * control register when reading and writing to Lincroft
217 * registers, respectively.
218 *
219 * We're interested in registers found in the Lincroft
220 * B-unit. The B-unit port is 0x3.
221 *
222 * The six B-unit RAR register offsets we use are listed
223 * earlier in this file.
224 *
225 * Lastly writing to the MCR register requires the "Byte
226 * enables" bits to be set to 1. This may be achieved by
227 * writing 0xF at bit 4.
228 *
229 * The MDR (message data register) format is the following:
230 * 1. [31:0]: Read/Write Data
231 *
232 * Data being read from this register is only available after
233 * writing the appropriate control message to the MCR
234 * register.
235 *
236 * Data being written to this register must be written before
237 * writing the appropriate control message to the MCR
238 * register.
239 */
Alan Cox542385e2009-08-06 20:44:18 +0100240
Mark Allyn433e63c2010-02-05 10:53:18 -0800241 int result;
Alan Cox375d65d2010-05-04 20:40:12 +0100242 u32 addr32;
Alan Cox542385e2009-08-06 20:44:18 +0100243
Mark Allyn433e63c2010-02-05 10:53:18 -0800244 /* Construct control message */
245 u32 const message =
246 (LNC_MESSAGE_READ_OPCODE << 24)
247 | (LNC_BUNIT_PORT << 16)
248 | (offset << 8)
249 | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
Alan Cox542385e2009-08-06 20:44:18 +0100250
Mark Allyn433e63c2010-02-05 10:53:18 -0800251 dev_dbg(&pdev->dev, "Offset for 'get' LNC MSG is %x\n", offset);
252
Mark Allyn433e63c2010-02-05 10:53:18 -0800253 /*
254 * We synchronize access to the Lincroft MCR and MDR registers
255 * until BOTH the command is issued through the MCR register
256 * and the corresponding data is read from the MDR register.
257 * Otherwise a race condition would exist between accesses to
258 * both registers.
259 */
260
261 mutex_lock(&lnc_reg_mutex);
262
263 /* Send the control message */
264 result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message);
Mark Allyn433e63c2010-02-05 10:53:18 -0800265 if (!result) {
Alan Cox375d65d2010-05-04 20:40:12 +0100266 /* Read back the address as a 32bit value */
267 result = pci_read_config_dword(pdev, LNC_MDR_OFFSET, &addr32);
268 *addr = (dma_addr_t)addr32;
Mark Allyn433e63c2010-02-05 10:53:18 -0800269 }
Mark Allyn433e63c2010-02-05 10:53:18 -0800270 mutex_unlock(&lnc_reg_mutex);
Mark Allyn433e63c2010-02-05 10:53:18 -0800271 return result;
272}
273
Alan Cox375d65d2010-05-04 20:40:12 +0100274/**
275 * rar_set_addr - Set a RAR mapping
276 * @pdev: PCI device for the RAR
277 * @offset: offset for message
278 * @addr: address to set
279 *
280 * Sets the address of a given RAR register. Returns 0 on success
281 * or an error code on failure.
282 */
283static int rar_set_addr(struct pci_dev *pdev,
Mark Allyn433e63c2010-02-05 10:53:18 -0800284 int offset,
285 dma_addr_t addr)
286{
287 /*
288 * Data being written to this register must be written before
289 * writing the appropriate control message to the MCR
290 * register.
Alan Cox375d65d2010-05-04 20:40:12 +0100291 * See rar_get_addrs() for a description of the
Mark Allyn433e63c2010-02-05 10:53:18 -0800292 * message bus interface being used here.
293 */
294
Alan Cox375d65d2010-05-04 20:40:12 +0100295 int result;
Mark Allyn433e63c2010-02-05 10:53:18 -0800296
297 /* Construct control message */
298 u32 const message = (LNC_MESSAGE_WRITE_OPCODE << 24)
299 | (LNC_BUNIT_PORT << 16)
300 | (offset << 8)
301 | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
302
Mark Allyn433e63c2010-02-05 10:53:18 -0800303 /*
304 * We synchronize access to the Lincroft MCR and MDR registers
305 * until BOTH the command is issued through the MCR register
306 * and the corresponding data is read from the MDR register.
307 * Otherwise a race condition would exist between accesses to
308 * both registers.
309 */
310
311 mutex_lock(&lnc_reg_mutex);
312
313 /* Send the control message */
314 result = pci_write_config_dword(pdev, LNC_MDR_OFFSET, addr);
Alan Cox375d65d2010-05-04 20:40:12 +0100315 if (!result)
316 /* And address */
Mark Allyn433e63c2010-02-05 10:53:18 -0800317 result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message);
318
Mark Allyn433e63c2010-02-05 10:53:18 -0800319 mutex_unlock(&lnc_reg_mutex);
Mark Allyn433e63c2010-02-05 10:53:18 -0800320 return result;
321}
322
323/*
Alan Cox375d65d2010-05-04 20:40:12 +0100324 * rar_init_params - Initialize RAR parameters
325 * @rar: RAR device to initialise
326 *
327 * Initialize RAR parameters, such as bus addresses, etc. Returns 0
328 * on success, or an error code on failure.
329 */
330static int init_rar_params(struct rar_device *rar)
Mark Allyn433e63c2010-02-05 10:53:18 -0800331{
Alan Cox375d65d2010-05-04 20:40:12 +0100332 struct pci_dev *pdev = rar->rar_dev;
Mark Allyn433e63c2010-02-05 10:53:18 -0800333 unsigned int i;
334 int result = 0;
Alan Cox375d65d2010-05-04 20:40:12 +0100335 int offset = 0x10; /* RAR 0 to 2 in order low/high/low/high/... */
Mark Allyn433e63c2010-02-05 10:53:18 -0800336
337 /* Retrieve RAR start and end bus addresses.
338 * Access the RAR registers through the Lincroft Message Bus
339 * Interface on PCI device: 00:00.0 Host bridge.
340 */
341
342 for (i = 0; i < MRST_NUM_RAR; ++i) {
Alan Cox375d65d2010-05-04 20:40:12 +0100343 struct rar_addr *addr = &rar->rar_addr[i];
Mark Allyn433e63c2010-02-05 10:53:18 -0800344
Alan Cox375d65d2010-05-04 20:40:12 +0100345 result = rar_read_addr(pdev, offset++, &addr->low);
346 if (result != 0)
347 return result;
348
349 result = rar_read_addr(pdev, offset++, &addr->high);
350 if (result != 0)
351 return result;
352
Mark Allyn433e63c2010-02-05 10:53:18 -0800353
354 /*
355 * Only the upper 22 bits of the RAR addresses are
356 * stored in their corresponding RAR registers so we
357 * must set the lower 10 bits accordingly.
358
359 * The low address has its lower 10 bits cleared, and
360 * the high address has all its lower 10 bits set,
361 * e.g.:
362 * low = 0x2ffffc00
363 */
364
365 addr->low &= (dma_addr_t)0xfffffc00u;
366
367 /*
368 * Set bits 9:0 on uppser address if bits 31:10 are non
369 * zero; otherwize clear all bits
370 */
371
372 if ((addr->high & 0xfffffc00u) == 0)
373 addr->high = 0;
374 else
375 addr->high |= 0x3ffu;
376 }
Alan Cox542385e2009-08-06 20:44:18 +0100377 /* Done accessing the device. */
Alan Cox542385e2009-08-06 20:44:18 +0100378
379 if (result == 0) {
Alan Cox375d65d2010-05-04 20:40:12 +0100380 for (i = 0; i != MRST_NUM_RAR; ++i) {
Mark Allyn433e63c2010-02-05 10:53:18 -0800381 /*
382 * "BRAR" refers to the RAR registers in the
383 * Lincroft B-unit.
384 */
385 dev_info(&pdev->dev, "BRAR[%u] bus address range = "
Alan Cox375d65d2010-05-04 20:40:12 +0100386 "[%lx, %lx]\n", i,
387 (unsigned long)rar->rar_addr[i].low,
388 (unsigned long)rar->rar_addr[i].high);
Benjamin Adolphif3557cc2009-12-31 21:54:46 +1300389 }
Alan Cox542385e2009-08-06 20:44:18 +0100390 }
Alan Cox542385e2009-08-06 20:44:18 +0100391 return result;
392}
393
Alan Cox375d65d2010-05-04 20:40:12 +0100394/**
395 * rar_get_address - get the bus address in a RAR
396 * @start: return value of start address of block
397 * @end: return value of end address of block
Mark Allyn433e63c2010-02-05 10:53:18 -0800398 *
Alan Cox375d65d2010-05-04 20:40:12 +0100399 * The rar_get_address function is used by other device drivers
400 * to obtain RAR address information on a RAR. It takes three
401 * parameters:
Mark Allyn433e63c2010-02-05 10:53:18 -0800402 *
Alan Cox375d65d2010-05-04 20:40:12 +0100403 * The function returns a 0 upon success or an error if there is no RAR
404 * facility on this system.
Mark Allyn433e63c2010-02-05 10:53:18 -0800405 */
Alan Cox375d65d2010-05-04 20:40:12 +0100406int rar_get_address(int rar_index, dma_addr_t *start, dma_addr_t *end)
Alan Cox542385e2009-08-06 20:44:18 +0100407{
Alan Cox375d65d2010-05-04 20:40:12 +0100408 int idx;
409 struct rar_device *rar = rar_to_device(rar_index, &idx);
Mark Allyn433e63c2010-02-05 10:53:18 -0800410
Alan Cox375d65d2010-05-04 20:40:12 +0100411 if (rar == NULL) {
412 WARN_ON(1);
413 return -ENODEV;
Mark Allyn433e63c2010-02-05 10:53:18 -0800414 }
415
Alan Cox375d65d2010-05-04 20:40:12 +0100416 *start = rar->rar_addr[idx].low;
417 *end = rar->rar_addr[idx].high;
418 return 0;
Mark Allyn433e63c2010-02-05 10:53:18 -0800419}
420EXPORT_SYMBOL(rar_get_address);
421
Alan Cox375d65d2010-05-04 20:40:12 +0100422/**
423 * rar_lock - lock a RAR register
424 * @rar_index: RAR to lock (0-2)
Mark Allyn433e63c2010-02-05 10:53:18 -0800425 *
Alan Cox375d65d2010-05-04 20:40:12 +0100426 * The rar_lock function is ued by other device drivers to lock an RAR.
427 * once a RAR is locked, it stays locked until the next system reboot.
Mark Allyn433e63c2010-02-05 10:53:18 -0800428 *
Alan Cox375d65d2010-05-04 20:40:12 +0100429 * The function returns a 0 upon success or an error if there is no RAR
430 * facility on this system, or the locking fails
Mark Allyn433e63c2010-02-05 10:53:18 -0800431 */
432int rar_lock(int rar_index)
433{
Alan Cox375d65d2010-05-04 20:40:12 +0100434 struct rar_device *rar;
435 int result;
436 int idx;
437 dma_addr_t low, high;
Mark Allyn433e63c2010-02-05 10:53:18 -0800438
Alan Cox375d65d2010-05-04 20:40:12 +0100439 rar = rar_to_device(rar_index, &idx);
440
441 if (rar == NULL) {
442 WARN_ON(1);
443 return -EINVAL;
Mark Allyn433e63c2010-02-05 10:53:18 -0800444 }
445
Alan Cox375d65d2010-05-04 20:40:12 +0100446 low = rar->rar_addr[idx].low & 0xfffffc00u;
447 high = rar->rar_addr[idx].high & 0xfffffc00u;
Mark Allyn433e63c2010-02-05 10:53:18 -0800448
Alan Cox375d65d2010-05-04 20:40:12 +0100449 /*
450 * Only allow I/O from the graphics and Langwell;
451 * not from the x86 processor
452 */
Mark Allyn433e63c2010-02-05 10:53:18 -0800453
Alan Cox375d65d2010-05-04 20:40:12 +0100454 if (rar_index == RAR_TYPE_VIDEO) {
455 low |= 0x00000009;
456 high |= 0x00000015;
457 } else if (rar_index == RAR_TYPE_AUDIO) {
458 /* Only allow I/O from Langwell; nothing from x86 */
459 low |= 0x00000008;
460 high |= 0x00000018;
461 } else
462 /* Read-only from all agents */
463 high |= 0x00000018;
Mark Allyn433e63c2010-02-05 10:53:18 -0800464
Alan Cox375d65d2010-05-04 20:40:12 +0100465 /*
466 * Now program the register using the Lincroft message
467 * bus interface.
468 */
469 result = rar_set_addr(rar->rar_dev,
470 2 * idx, low);
Mark Allyn433e63c2010-02-05 10:53:18 -0800471
Alan Cox375d65d2010-05-04 20:40:12 +0100472 if (result == 0)
473 result = rar_set_addr(rar->rar_dev,
474 2 * idx + 1, high);
Mark Allyn433e63c2010-02-05 10:53:18 -0800475
Mark Allyn433e63c2010-02-05 10:53:18 -0800476 return result;
477}
478EXPORT_SYMBOL(rar_lock);
479
Alan Cox375d65d2010-05-04 20:40:12 +0100480/**
481 * register_rar - register a RAR handler
482 * @num: RAR we wish to register for
483 * @callback: function to call when RAR support is available
484 * @data: data to pass to this function
485 *
486 * The register_rar function is to used by other device drivers
487 * to ensure that this driver is ready. As we cannot be sure of
Lucas De Marchic8440332011-03-17 17:18:22 -0300488 * the compile/execute order of drivers in the kernel, it is
Alan Cox375d65d2010-05-04 20:40:12 +0100489 * best to give this driver a callback function to call when
490 * it is ready to give out addresses. The callback function
491 * would have those steps that continue the initialization of
492 * a driver that do require a valid RAR address. One of those
493 * steps would be to call rar_get_address()
494 *
Alan Coxc715a382010-06-18 14:05:52 +0100495 * This function return 0 on success or an error code on failure.
Alan Cox375d65d2010-05-04 20:40:12 +0100496 */
497int register_rar(int num, int (*callback)(unsigned long data),
498 unsigned long data)
Mark Allyn433e63c2010-02-05 10:53:18 -0800499{
Alan Cox375d65d2010-05-04 20:40:12 +0100500 /* For now we hardcode a single RAR device */
501 struct rar_device *rar;
502 struct client *c;
503 int idx;
504 int retval = 0;
Mark Allyn433e63c2010-02-05 10:53:18 -0800505
506 mutex_lock(&rar_mutex);
507
Alan Cox375d65d2010-05-04 20:40:12 +0100508 /* Do we have a client mapping for this RAR number ? */
509 c = rar_to_client(num);
510 if (c == NULL) {
511 retval = -ERANGE;
512 goto done;
513 }
514 /* Is it claimed ? */
515 if (c->busy) {
516 retval = -EBUSY;
517 goto done;
518 }
519 c->busy = 1;
Mark Allyn433e63c2010-02-05 10:53:18 -0800520
Alan Cox375d65d2010-05-04 20:40:12 +0100521 /* See if we have a handler for this RAR yet, if we do then fire it */
522 rar = rar_to_device(num, &idx);
523
524 if (rar) {
Mark Allyn433e63c2010-02-05 10:53:18 -0800525 /*
526 * if the driver already registered, then we can simply
527 * call the callback right now
528 */
Alan Cox375d65d2010-05-04 20:40:12 +0100529 (*callback)(data);
530 goto done;
Mark Allyn433e63c2010-02-05 10:53:18 -0800531 }
532
Alan Cox375d65d2010-05-04 20:40:12 +0100533 /* Arrange to be called back when the hardware is found */
534 c->callback = callback;
535 c->driver_priv = data;
536done:
Mark Allyn433e63c2010-02-05 10:53:18 -0800537 mutex_unlock(&rar_mutex);
Alan Cox375d65d2010-05-04 20:40:12 +0100538 return retval;
Mark Allyn433e63c2010-02-05 10:53:18 -0800539}
540EXPORT_SYMBOL(register_rar);
541
Alan Cox375d65d2010-05-04 20:40:12 +0100542/**
543 * unregister_rar - release a RAR allocation
544 * @num: RAR number
545 *
546 * Releases a RAR allocation, or pending allocation. If a callback is
547 * pending then this function will either complete before the unregister
548 * returns or not at all.
549 */
550
551void unregister_rar(int num)
Mark Allyn3913add2010-02-05 10:53:34 -0800552{
Alan Cox375d65d2010-05-04 20:40:12 +0100553 struct client *c;
554
555 mutex_lock(&rar_mutex);
556 c = rar_to_client(num);
557 if (c == NULL || !c->busy)
558 WARN_ON(1);
559 else
560 c->busy = 0;
561 mutex_unlock(&rar_mutex);
562}
563EXPORT_SYMBOL(unregister_rar);
564
565/**
566 * rar_callback - Process callbacks
567 * @rar: new RAR device
568 *
569 * Process the callbacks for a newly found RAR device.
570 */
571
572static void rar_callback(struct rar_device *rar)
573{
574 struct client *c = &rar->client[0];
575 int i;
576
577 mutex_lock(&rar_mutex);
578
579 rar->registered = 1; /* Ensure no more callbacks queue */
580
581 for (i = 0; i < MRST_NUM_RAR; i++) {
582 if (c->callback && c->busy) {
583 c->callback(c->driver_priv);
584 c->callback = NULL;
585 }
586 c++;
587 }
588 mutex_unlock(&rar_mutex);
Mark Allyn3913add2010-02-05 10:53:34 -0800589}
590
Alan Cox375d65d2010-05-04 20:40:12 +0100591/**
592 * rar_probe - PCI probe callback
593 * @dev: PCI device
594 * @id: matching entry in the match table
595 *
596 * A RAR device has been discovered. Initialise it and if successful
597 * process any pending callbacks that can now be completed.
Mark Allyn433e63c2010-02-05 10:53:18 -0800598 */
599static int rar_probe(struct pci_dev *dev, const struct pci_device_id *id)
600{
Alan Cox542385e2009-08-06 20:44:18 +0100601 int error;
Alan Cox375d65d2010-05-04 20:40:12 +0100602 struct rar_device *rar;
Alan Cox542385e2009-08-06 20:44:18 +0100603
Mark Allyn433e63c2010-02-05 10:53:18 -0800604 dev_dbg(&dev->dev, "PCI probe starting\n");
Alan Cox542385e2009-08-06 20:44:18 +0100605
Alan Cox375d65d2010-05-04 20:40:12 +0100606 rar = alloc_rar_device();
607 if (rar == NULL)
608 return -EBUSY;
609
610 /* Enable the device */
Mark Allyn433e63c2010-02-05 10:53:18 -0800611 error = pci_enable_device(dev);
Alan Cox542385e2009-08-06 20:44:18 +0100612 if (error) {
Mark Allyn433e63c2010-02-05 10:53:18 -0800613 dev_err(&dev->dev,
614 "Error enabling RAR register PCI device\n");
Alan Cox542385e2009-08-06 20:44:18 +0100615 goto end_function;
616 }
617
Alan Cox375d65d2010-05-04 20:40:12 +0100618 /* Fill in the rar_device structure */
619 rar->rar_dev = pci_dev_get(dev);
620 pci_set_drvdata(dev, rar);
Alan Cox542385e2009-08-06 20:44:18 +0100621
Mark Allyn433e63c2010-02-05 10:53:18 -0800622 /*
Alan Cox375d65d2010-05-04 20:40:12 +0100623 * Initialize the RAR parameters, which have to be retrieved
624 * via the message bus interface.
625 */
626 error = init_rar_params(rar);
Alan Cox542385e2009-08-06 20:44:18 +0100627 if (error) {
Mark Allyn433e63c2010-02-05 10:53:18 -0800628 pci_disable_device(dev);
Alan Cox375d65d2010-05-04 20:40:12 +0100629 dev_err(&dev->dev, "Error retrieving RAR addresses\n");
Alan Cox542385e2009-08-06 20:44:18 +0100630 goto end_function;
Mark Allyn433e63c2010-02-05 10:53:18 -0800631 }
Mark Allyn433e63c2010-02-05 10:53:18 -0800632 /* now call anyone who has registered (using callbacks) */
Alan Cox375d65d2010-05-04 20:40:12 +0100633 rar_callback(rar);
634 return 0;
Alan Cox542385e2009-08-06 20:44:18 +0100635end_function:
Alan Cox375d65d2010-05-04 20:40:12 +0100636 free_rar_device(rar);
Alan Cox542385e2009-08-06 20:44:18 +0100637 return error;
638}
639
Mark Allyn433e63c2010-02-05 10:53:18 -0800640const struct pci_device_id rar_pci_id_tbl[] = {
Alan Cox375d65d2010-05-04 20:40:12 +0100641 { PCI_VDEVICE(INTEL, 0x4110) },
Mark Allyn433e63c2010-02-05 10:53:18 -0800642 { 0 }
643};
644
645MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl);
646
647const struct pci_device_id *my_id_table = rar_pci_id_tbl;
648
649/* field for registering driver to PCI device */
650static struct pci_driver rar_pci_driver = {
651 .name = "rar_register_driver",
652 .id_table = rar_pci_id_tbl,
Mark Allyn3913add2010-02-05 10:53:34 -0800653 .probe = rar_probe,
Alan Cox375d65d2010-05-04 20:40:12 +0100654 /* Cannot be unplugged - no remove */
Mark Allyn433e63c2010-02-05 10:53:18 -0800655};
656
Alan Cox542385e2009-08-06 20:44:18 +0100657static int __init rar_init_handler(void)
658{
659 return pci_register_driver(&rar_pci_driver);
660}
661
662static void __exit rar_exit_handler(void)
663{
664 pci_unregister_driver(&rar_pci_driver);
665}
666
667module_init(rar_init_handler);
668module_exit(rar_exit_handler);
669
670MODULE_LICENSE("GPL");
Mark Allyn433e63c2010-02-05 10:53:18 -0800671MODULE_DESCRIPTION("Intel Restricted Access Region Register Driver");