[PATCH] patch 1/8] pciehp: use the PCI core for hotplug resource management
[firefly-linux-kernel-4.4.55.git] / drivers / pci / hotplug / pciehprm_acpi.c
1 /*
2  * PCIEHPRM ACPI: PHP Resource Manager for ACPI platform
3  *
4  * Copyright (C) 2003-2004 Intel Corporation
5  *
6  * All rights reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or (at
11  * your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16  * NON INFRINGEMENT.  See the GNU General Public License for more
17  * details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  * Send feedback to <kristen.c.accardi@intel.com>
24  *
25  */
26
27 #include <linux/config.h>
28 #include <linux/module.h>
29 #include <linux/kernel.h>
30 #include <linux/types.h>
31 #include <linux/pci.h>
32 #include <linux/init.h>
33 #include <linux/acpi.h>
34 #include <linux/efi.h>
35 #include <linux/pci-acpi.h>
36 #include <asm/uaccess.h>
37 #include <asm/system.h>
38 #include <acpi/acpi.h>
39 #include <acpi/acpi_bus.h>
40 #include <acpi/actypes.h>
41 #include "pciehp.h"
42 #include "pciehprm.h"
43
44 #define PCI_MAX_BUS             0x100
45 #define ACPI_STA_DEVICE_PRESENT 0x01
46
47 #define METHOD_NAME__SUN        "_SUN"
48 #define METHOD_NAME__HPP        "_HPP"
49 #define METHOD_NAME_OSHP        "OSHP"
50
51 /* Status code for running acpi method to gain native control */
52 #define NC_NOT_RUN      0
53 #define OSC_NOT_EXIST   1
54 #define OSC_RUN_FAILED  2
55 #define OSHP_NOT_EXIST  3
56 #define OSHP_RUN_FAILED 4
57 #define NC_RUN_SUCCESS  5
58
59 #define PHP_RES_BUS             0xA0
60 #define PHP_RES_IO              0xA1
61 #define PHP_RES_MEM             0xA2
62 #define PHP_RES_PMEM            0xA3
63
64 #define BRIDGE_TYPE_P2P         0x00
65 #define BRIDGE_TYPE_HOST        0x01
66
67 /* this should go to drivers/acpi/include/ */
68 struct acpi__hpp {
69         u8      cache_line_size;
70         u8      latency_timer;
71         u8      enable_serr;
72         u8      enable_perr;
73 };
74
75 struct acpi_php_slot {
76         struct acpi_php_slot    *next;
77         struct acpi_bridge      *bridge;
78         acpi_handle     handle;
79         int     seg;
80         int     bus;
81         int     dev;
82         int     fun;
83         u32     sun;
84         void    *slot_ops;      /* _STA, _EJx, etc */
85         struct slot *slot;
86 };              /* per func */
87
88 struct acpi_bridge {
89         struct acpi_bridge      *parent;
90         struct acpi_bridge      *next;
91         struct acpi_bridge      *child;
92         acpi_handle     handle;
93         int seg;
94         int pbus;                       /* pdev->bus->number            */
95         int pdevice;                    /* PCI_SLOT(pdev->devfn)        */
96         int pfunction;                  /* PCI_DEVFN(pdev->devfn)       */
97         int bus;                        /* pdev->subordinate->number    */
98         struct acpi__hpp                *_hpp;
99         struct acpi_php_slot    *slots;
100         int scanned;
101         int type;
102 };
103
104 static struct acpi_bridge *acpi_bridges_head;
105
106 static u8 * acpi_path_name( acpi_handle handle)
107 {
108         acpi_status             status;
109         static u8               path_name[ACPI_PATHNAME_MAX];
110         struct acpi_buffer      ret_buf = { ACPI_PATHNAME_MAX, path_name };
111
112         memset(path_name, 0, sizeof (path_name));
113         status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf);
114
115         if (ACPI_FAILURE(status))
116                 return NULL;
117         else
118                 return path_name;       
119 }
120
121 static void acpi_get__hpp ( struct acpi_bridge  *ab);
122 static int acpi_run_oshp ( struct acpi_bridge   *ab);
123 static int osc_run_status = NC_NOT_RUN;
124 static int oshp_run_status = NC_NOT_RUN;
125
126 static int acpi_add_slot_to_php_slots(
127         struct acpi_bridge      *ab,
128         int                     bus_num,
129         acpi_handle             handle,
130         u32                     adr,
131         u32                     sun
132         )
133 {
134         struct acpi_php_slot    *aps;
135         static long     samesun = -1;
136
137         aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
138         if (!aps) {
139                 err ("acpi_pciehprm: alloc for aps fail\n");
140                 return -1;
141         }
142         memset(aps, 0, sizeof(struct acpi_php_slot));
143
144         aps->handle = handle;
145         aps->bus = bus_num;
146         aps->dev = (adr >> 16) & 0xffff;
147         aps->fun = adr & 0xffff;
148         aps->sun = sun;
149
150         aps->next = ab->slots;  /* cling to the bridge */
151         aps->bridge = ab;
152         ab->slots = aps;
153
154         ab->scanned += 1;
155         if (!ab->_hpp)
156                 acpi_get__hpp(ab);
157         
158         if (osc_run_status == OSC_NOT_EXIST)
159                 oshp_run_status = acpi_run_oshp(ab);
160
161         if (sun != samesun) {
162                 info("acpi_pciehprm:   Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n", 
163                         aps->sun, ab->seg, aps->bus, aps->dev, aps->fun);
164                 samesun = sun;
165         }
166         return 0;
167 }
168
169 static void acpi_get__hpp ( struct acpi_bridge  *ab)
170 {
171         acpi_status             status;
172         u8                      nui[4];
173         struct acpi_buffer      ret_buf = { 0, NULL};
174         union acpi_object       *ext_obj, *package;
175         u8                      *path_name = acpi_path_name(ab->handle);
176         int                     i, len = 0;
177
178         /* get _hpp */
179         status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
180         switch (status) {
181         case AE_BUFFER_OVERFLOW:
182                 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
183                 if (!ret_buf.pointer) {
184                         err ("acpi_pciehprm:%s alloc for _HPP fail\n", path_name);
185                         return;
186                 }
187                 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf);
188                 if (ACPI_SUCCESS(status))
189                         break;
190         default:
191                 if (ACPI_FAILURE(status)) {
192                         err("acpi_pciehprm:%s _HPP fail=0x%x\n", path_name, status);
193                         return;
194                 }
195         }
196
197         ext_obj = (union acpi_object *) ret_buf.pointer;
198         if (ext_obj->type != ACPI_TYPE_PACKAGE) {
199                 err ("acpi_pciehprm:%s _HPP obj not a package\n", path_name);
200                 goto free_and_return;
201         }
202
203         len = ext_obj->package.count;
204         package = (union acpi_object *) ret_buf.pointer;
205         for ( i = 0; (i < len) || (i < 4); i++) {
206                 ext_obj = (union acpi_object *) &package->package.elements[i];
207                 switch (ext_obj->type) {
208                 case ACPI_TYPE_INTEGER:
209                         nui[i] = (u8)ext_obj->integer.value;
210                         break;
211                 default:
212                         err ("acpi_pciehprm:%s _HPP obj type incorrect\n", path_name);
213                         goto free_and_return;
214                 }
215         }
216
217         ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL);
218         if (!ab->_hpp) {
219                 err ("acpi_pciehprm:%s alloc for _HPP failed\n", path_name);
220                 goto free_and_return;
221         }
222         memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
223
224         ab->_hpp->cache_line_size       = nui[0];
225         ab->_hpp->latency_timer         = nui[1];
226         ab->_hpp->enable_serr           = nui[2];
227         ab->_hpp->enable_perr           = nui[3];
228
229         dbg("  _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
230         dbg("  _HPP: latency timer  =0x%x\n", ab->_hpp->latency_timer);
231         dbg("  _HPP: enable SERR    =0x%x\n", ab->_hpp->enable_serr);
232         dbg("  _HPP: enable PERR    =0x%x\n", ab->_hpp->enable_perr);
233
234 free_and_return:
235         kfree(ret_buf.pointer);
236 }
237
238 static int acpi_run_oshp ( struct acpi_bridge   *ab)
239 {
240         acpi_status             status;
241         u8                      *path_name = acpi_path_name(ab->handle);
242
243         /* run OSHP */
244         status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL);
245         if (ACPI_FAILURE(status)) {
246                 err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status);
247                 oshp_run_status = (status == AE_NOT_FOUND) ? OSHP_NOT_EXIST : OSHP_RUN_FAILED;
248         } else {
249                 oshp_run_status = NC_RUN_SUCCESS;
250                 dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
251                 dbg("acpi_pciehprm:%s oshp_run_status =0x%x\n", path_name, oshp_run_status);
252         }
253         return oshp_run_status;
254 }
255
256 /* find acpi_bridge downword from ab.  */
257 static struct acpi_bridge *
258 find_acpi_bridge_by_bus(
259         struct acpi_bridge *ab,
260         int seg,
261         int bus         /* pdev->subordinate->number */
262         )
263 {
264         struct acpi_bridge      *lab = NULL;
265
266         if (!ab)
267                 return NULL;
268
269         if ((ab->bus == bus) && (ab->seg == seg))
270                 return ab;
271
272         if (ab->child)
273                 lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
274
275         if (!lab)
276         if (ab->next)
277                 lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
278
279         return lab;
280 }
281
282 /*
283  * Build a device tree of ACPI PCI Bridges
284  */
285 static void pciehprm_acpi_register_a_bridge (
286         struct acpi_bridge      **head,
287         struct acpi_bridge      *pab,   /* parent bridge to which child bridge is added */
288         struct acpi_bridge      *cab    /* child bridge to add */
289         )
290 {
291         struct acpi_bridge      *lpab;
292         struct acpi_bridge      *lcab;
293
294         lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
295         if (!lpab) {
296                 if (!(pab->type & BRIDGE_TYPE_HOST))
297                         warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
298                 pab->next = *head;
299                 *head = pab;
300                 lpab = pab;
301         }
302
303         if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
304                 return;
305
306         lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
307         if (lcab) {
308                 if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
309                         err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
310                 return;
311         } else
312                 lcab = cab;
313
314         lcab->parent = lpab;
315         lcab->next = lpab->child;
316         lpab->child = lcab;
317 }
318
319 static acpi_status pciehprm_acpi_build_php_slots_callback(
320         acpi_handle             handle,
321         u32                     Level,
322         void                    *context,
323         void                    **retval
324         )
325 {
326         ulong           bus_num;
327         ulong           seg_num;
328         ulong           sun, adr;
329         ulong           padr = 0;
330         acpi_handle             phandle = NULL;
331         struct acpi_bridge      *pab = (struct acpi_bridge *)context;
332         struct acpi_bridge      *lab;
333         acpi_status             status;
334         u8                      *path_name = acpi_path_name(handle);
335
336         /* get _SUN */
337         status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun);
338         switch(status) {
339         case AE_NOT_FOUND:
340                 return AE_OK;
341         default:
342                 if (ACPI_FAILURE(status)) {
343                         err("acpi_pciehprm:%s _SUN fail=0x%x\n", path_name, status);
344                         return status;
345                 }
346         }
347
348         /* get _ADR. _ADR must exist if _SUN exists */
349         status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
350         if (ACPI_FAILURE(status)) {
351                 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
352                 return status;
353         }
354
355         dbg("acpi_pciehprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
356
357         status = acpi_get_parent(handle, &phandle);
358         if (ACPI_FAILURE(status)) {
359                 err("acpi_pciehprm:%s get_parent fail=0x%x\n", path_name, status);
360                 return (status);
361         }
362
363         bus_num = pab->bus;
364         seg_num = pab->seg;
365
366         if (pab->bus == bus_num) {
367                 lab = pab;
368         } else {
369                 dbg("WARN: pab is not parent\n");
370                 lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
371                 if (!lab) {
372                         dbg("acpi_pciehprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
373                         lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
374                         if (!lab) {
375                                 err("acpi_pciehprm: alloc for ab fail\n");
376                                 return AE_NO_MEMORY;
377                         }
378                         memset(lab, 0, sizeof(struct acpi_bridge));
379
380                         lab->handle = phandle;
381                         lab->pbus = pab->bus;
382                         lab->pdevice = (int)(padr >> 16) & 0xffff;
383                         lab->pfunction = (int)(padr & 0xffff);
384                         lab->bus = (int)bus_num;
385                         lab->scanned = 0;
386                         lab->type = BRIDGE_TYPE_P2P;
387
388                         pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
389                 } else
390                         dbg("acpi_pciehprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
391         }
392
393         acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
394
395         return (status);
396 }
397
398 static int pciehprm_acpi_build_php_slots(
399         struct acpi_bridge      *ab,
400         u32                     depth
401         )
402 {
403         acpi_status     status;
404         u8              *path_name = acpi_path_name(ab->handle);
405
406         /* Walk down this pci bridge to get _SUNs if any behind P2P */
407         status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
408                                 ab->handle,
409                                 depth,
410                                 pciehprm_acpi_build_php_slots_callback,
411                                 ab,
412                                 NULL );
413         if (ACPI_FAILURE(status)) {
414                 dbg("acpi_pciehprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status);
415                 return -1;
416         }
417
418         return 0;
419 }
420
421 static void build_a_bridge(
422         struct acpi_bridge      *pab,
423         struct acpi_bridge      *ab
424         )
425 {
426         u8              *path_name = acpi_path_name(ab->handle);
427
428         pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
429
430         switch (ab->type) {
431         case BRIDGE_TYPE_HOST:
432                 dbg("acpi_pciehprm: Registered PCI HOST Bridge(%02x)    on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
433                         ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
434                 break;
435         case BRIDGE_TYPE_P2P:
436                 dbg("acpi_pciehprm: Registered PCI  P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
437                         ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
438                 break;
439         };
440
441         /* build any immediate PHP slots under this pci bridge */
442         pciehprm_acpi_build_php_slots(ab, 1);
443 }
444
445 static struct acpi_bridge * add_p2p_bridge(
446         acpi_handle handle,
447         struct acpi_bridge      *pab,   /* parent */
448         ulong   adr
449         )
450 {
451         struct acpi_bridge      *ab;
452         struct pci_dev  *pdev;
453         ulong           devnum, funcnum;
454         u8                      *path_name = acpi_path_name(handle);
455
456         ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
457         if (!ab) {
458                 err("acpi_pciehprm: alloc for ab fail\n");
459                 return NULL;
460         }
461         memset(ab, 0, sizeof(struct acpi_bridge));
462
463         devnum = (adr >> 16) & 0xffff;
464         funcnum = adr & 0xffff;
465
466         pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
467         if (!pdev || !pdev->subordinate) {
468                 err("acpi_pciehprm:%s is not a P2P Bridge\n", path_name);
469                 kfree(ab);
470                 return NULL;
471         }
472
473         ab->handle = handle;
474         ab->seg = pab->seg;
475         ab->pbus = pab->bus;            /* or pdev->bus->number */
476         ab->pdevice = devnum;           /* or PCI_SLOT(pdev->devfn) */
477         ab->pfunction = funcnum;        /* or PCI_FUNC(pdev->devfn) */
478         ab->bus = pdev->subordinate->number;
479         ab->scanned = 0;
480         ab->type = BRIDGE_TYPE_P2P;
481
482         dbg("acpi_pciehprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
483                 pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
484                 pab->bus, (u32)devnum, (u32)funcnum, path_name);
485
486         build_a_bridge(pab, ab);
487
488         return ab;
489 }
490
491 static acpi_status scan_p2p_bridge(
492         acpi_handle             handle,
493         u32                     Level,
494         void                    *context,
495         void                    **retval
496         )
497 {
498         struct acpi_bridge      *pab = (struct acpi_bridge *)context;
499         struct acpi_bridge      *ab;
500         acpi_status             status;
501         ulong                   adr = 0;
502         u8                      *path_name = acpi_path_name(handle);
503         ulong                   devnum, funcnum;
504         struct pci_dev          *pdev;
505
506         /* get device, function */
507         status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
508         if (ACPI_FAILURE(status)) {
509                 if (status != AE_NOT_FOUND)
510                         err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
511                 return AE_OK;
512         }
513
514         devnum = (adr >> 16) & 0xffff;
515         funcnum = adr & 0xffff;
516
517         pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
518         if (!pdev)
519                 return AE_OK;
520         if (!pdev->subordinate)
521                 return AE_OK;
522
523         ab = add_p2p_bridge(handle, pab, adr);
524         if (ab) {
525                 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
526                                         handle,
527                                         (u32)1,
528                                         scan_p2p_bridge,
529                                         ab,
530                                         NULL);
531                 if (ACPI_FAILURE(status))
532                         dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
533         }
534
535         return AE_OK;
536 }
537
538 static struct acpi_bridge * add_host_bridge(
539         acpi_handle handle,
540         ulong   segnum,
541         ulong   busnum
542         )
543 {
544         ulong                   adr = 0;
545         acpi_status             status;
546         struct acpi_bridge      *ab;
547         u8                      *path_name = acpi_path_name(handle);
548
549         /* get device, function: host br adr is always 0000 though.  */
550         status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
551         if (ACPI_FAILURE(status)) {
552                 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
553                 return NULL;
554         }
555         dbg("acpi_pciehprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum, 
556                 (u32)busnum, (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
557
558         ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
559         if (!ab) {
560                 err("acpi_pciehprm: alloc for ab fail\n");
561                 return NULL;
562         }
563         memset(ab, 0, sizeof(struct acpi_bridge));
564
565         ab->handle = handle;
566         ab->seg = (int)segnum;
567         ab->bus = ab->pbus = (int)busnum;
568         ab->pdevice = (int)(adr >> 16) & 0xffff;
569         ab->pfunction = (int)(adr & 0xffff);
570         ab->scanned = 0;
571         ab->type = BRIDGE_TYPE_HOST;
572
573         status = pci_osc_control_set (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL); 
574         if (ACPI_FAILURE(status)) {
575                 err("%s: status %x\n", __FUNCTION__, status);
576                 osc_run_status = (status == AE_NOT_FOUND) ? OSC_NOT_EXIST : OSC_RUN_FAILED;
577         } else {
578                 osc_run_status = NC_RUN_SUCCESS;
579         }       
580         dbg("%s: osc_run_status %x\n", __FUNCTION__, osc_run_status);
581         
582         build_a_bridge(ab, ab);
583
584         return ab;
585 }
586
587 static acpi_status acpi_scan_from_root_pci_callback (
588         acpi_handle     handle,
589         u32                     Level,
590         void            *context,
591         void            **retval
592         )
593 {
594         ulong           segnum = 0;
595         ulong           busnum = 0;
596         acpi_status             status;
597         struct acpi_bridge      *ab;
598         u8                      *path_name = acpi_path_name(handle);
599
600         /* get bus number of this pci root bridge */
601         status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
602         if (ACPI_FAILURE(status)) {
603                 if (status != AE_NOT_FOUND) {
604                         err("acpi_pciehprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
605                         return status;
606                 }
607                 segnum = 0;
608         }
609
610         /* get bus number of this pci root bridge */
611         status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
612         if (ACPI_FAILURE(status)) {
613                 err("acpi_pciehprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
614                 return (status);
615         }
616
617         ab = add_host_bridge(handle, segnum, busnum);
618         if (ab) {
619                 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
620                                         handle,
621                                         1,
622                                         scan_p2p_bridge,
623                                         ab,
624                                         NULL);
625                 if (ACPI_FAILURE(status))
626                         dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
627         }
628
629         return AE_OK;
630 }
631
632 static int pciehprm_acpi_scan_pci (void)
633 {
634         acpi_status     status;
635
636         /*
637          * TBD: traverse LDM device tree with the help of
638          *  unified ACPI augmented for php device population.
639          */
640         status = acpi_get_devices ( PCI_ROOT_HID_STRING,
641                                 acpi_scan_from_root_pci_callback,
642                                 NULL,
643                                 NULL );
644         if (ACPI_FAILURE(status)) {
645                 err("acpi_pciehprm:get_device PCI ROOT HID fail=0x%x\n", status);
646                 return -1;
647         }
648
649         return 0;
650 }
651
652 int pciehprm_init(enum php_ctlr_type ctlr_type)
653 {
654         int     rc;
655
656         if (ctlr_type != PCI)
657                 return -ENODEV;
658
659         dbg("pciehprm ACPI init <enter>\n");
660         acpi_bridges_head = NULL;
661
662         /* construct PCI bus:device tree of acpi_handles */
663         rc = pciehprm_acpi_scan_pci();
664         if (rc)
665                 return rc;
666
667         if ((oshp_run_status != NC_RUN_SUCCESS) && (osc_run_status != NC_RUN_SUCCESS)) {
668                 err("Fails to gain control of native hot-plug\n");
669                 rc = -ENODEV;
670         }
671
672         dbg("pciehprm ACPI init %s\n", (rc)?"fail":"success");
673         return rc;
674 }
675
676 static void free_a_slot(struct acpi_php_slot *aps)
677 {
678         dbg("        free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun);
679
680         kfree(aps);
681 }
682
683 static void free_a_bridge( struct acpi_bridge   *ab)
684 {
685         struct acpi_php_slot    *aps, *next;
686
687         switch (ab->type) {
688         case BRIDGE_TYPE_HOST:
689                 dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
690                         ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
691                 break;
692         case BRIDGE_TYPE_P2P:
693                 dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
694                         ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
695                 break;
696         };
697
698         /* free slots first */
699         for (aps = ab->slots; aps; aps = next) {
700                 next = aps->next;
701                 free_a_slot(aps);
702         }
703
704         kfree(ab);
705 }
706
707 static void pciehprm_free_bridges ( struct acpi_bridge  *ab)
708 {
709         if (!ab)
710                 return;
711
712         if (ab->child)
713                 pciehprm_free_bridges (ab->child);
714
715         if (ab->next)
716                 pciehprm_free_bridges (ab->next);
717
718         free_a_bridge(ab);
719 }
720
721 void pciehprm_cleanup(void)
722 {
723         pciehprm_free_bridges (acpi_bridges_head);
724 }
725
726 static int get_number_of_slots (
727         struct acpi_bridge      *ab,
728         int                             selfonly
729         )
730 {
731         struct acpi_php_slot    *aps;
732         int     prev_slot = -1;
733         int     slot_num = 0;
734
735         for ( aps = ab->slots; aps; aps = aps->next)
736                 if (aps->dev != prev_slot) {
737                         prev_slot = aps->dev;
738                         slot_num++;
739                 }
740
741         if (ab->child)
742                 slot_num += get_number_of_slots (ab->child, 0);
743
744         if (selfonly)
745                 return slot_num;
746
747         if (ab->next)
748                 slot_num += get_number_of_slots (ab->next, 0);
749
750         return slot_num;
751 }
752
753 static struct acpi_php_slot * get_acpi_slot (
754         struct acpi_bridge *ab,
755         u32 sun
756         )
757 {
758         struct acpi_php_slot    *aps = NULL;
759
760         for ( aps = ab->slots; aps; aps = aps->next)
761                 if (aps->sun == sun)
762                         return aps;
763
764         if (!aps && ab->child) {
765                 aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
766                 if (aps)
767                         return aps;
768         }
769
770         if (!aps && ab->next) {
771                 aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
772                 if (aps)
773                         return aps;
774         }
775
776         return aps;
777
778 }
779
780 #if 0
781 void * pciehprm_get_slot(struct slot *slot)
782 {
783         struct acpi_bridge      *ab = acpi_bridges_head;
784         struct acpi_php_slot    *aps = get_acpi_slot (ab, slot->number);
785
786         aps->slot = slot;
787
788         dbg("Got acpi slot sun(%x): s:b:d:f(%x:%x:%x:%x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
789
790         return (void *)aps;
791 }
792 #endif
793
794 int pciehprm_set_hpp(
795         struct controller *ctrl,
796         struct pci_func *func,
797         u8      card_type
798         )
799 {
800         struct acpi_bridge      *ab;
801         struct pci_bus lpci_bus, *pci_bus;
802         int                             rc = 0;
803         unsigned int    devfn;
804         u8                              cls= 0x08;      /* default cache line size      */
805         u8                              lt = 0x40;      /* default latency timer        */
806         u8                              ep = 0;
807         u8                              es = 0;
808
809         memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
810         pci_bus = &lpci_bus;
811         pci_bus->number = func->bus;
812         devfn = PCI_DEVFN(func->device, func->function);
813
814         ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
815
816         if (ab) {
817                 if (ab->_hpp) {
818                         lt  = (u8)ab->_hpp->latency_timer;
819                         cls = (u8)ab->_hpp->cache_line_size;
820                         ep  = (u8)ab->_hpp->enable_perr;
821                         es  = (u8)ab->_hpp->enable_serr;
822                 } else
823                         dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
824         } else
825                 dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
826
827
828         if (card_type == PCI_HEADER_TYPE_BRIDGE) {
829                 /* set subordinate Latency Timer */
830                 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
831         }
832
833         /* set base Latency Timer */
834         rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
835         dbg("  set latency timer  =0x%02x: %x\n", lt, rc);
836
837         rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
838         dbg("  set cache_line_size=0x%02x: %x\n", cls, rc);
839
840         return rc;
841 }
842
843 void pciehprm_enable_card(
844         struct controller *ctrl,
845         struct pci_func *func,
846         u8 card_type)
847 {
848         u16 command, cmd, bcommand, bcmd;
849         struct pci_bus lpci_bus, *pci_bus;
850         struct acpi_bridge      *ab;
851         unsigned int devfn;
852         int rc;
853
854         memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
855         pci_bus = &lpci_bus;
856         pci_bus->number = func->bus;
857         devfn = PCI_DEVFN(func->device, func->function);
858
859         rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &cmd);
860
861         if (card_type == PCI_HEADER_TYPE_BRIDGE) {
862                 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcmd);
863         }
864
865         command  = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
866                 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
867         bcommand  = bcmd | PCI_BRIDGE_CTL_NO_ISA;
868
869         ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
870         if (ab) {
871                 if (ab->_hpp) {
872                         if (ab->_hpp->enable_perr) {
873                                 command |= PCI_COMMAND_PARITY;
874                                 bcommand |= PCI_BRIDGE_CTL_PARITY;
875                         } else {
876                                 command &= ~PCI_COMMAND_PARITY;
877                                 bcommand &= ~PCI_BRIDGE_CTL_PARITY;
878                         }
879                         if (ab->_hpp->enable_serr) {
880                                 command |= PCI_COMMAND_SERR;
881                                 bcommand |= PCI_BRIDGE_CTL_SERR;
882                         } else {
883                                 command &= ~PCI_COMMAND_SERR;
884                                 bcommand &= ~PCI_BRIDGE_CTL_SERR;
885                         }
886                 } else
887                         dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
888         } else
889                 dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
890
891         if (command != cmd) {
892                 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
893         }
894         if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
895                 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
896         }
897 }