File indexing completed on 2025-05-11 08:24:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #include <stdio.h>
0039 #include <stdlib.h>
0040 #include <string.h>
0041
0042 #include <drvmgr/drvmgr.h>
0043 #include <grlib/ambapp_bus.h>
0044
0045 #include <bsp.h>
0046 #include <grlib/ambapp.h>
0047 #include <rtems/bspIo.h>
0048
0049
0050 #define DBG(args...)
0051
0052
0053 struct grlib_gptimer_regs {
0054 volatile unsigned int scaler_value;
0055 volatile unsigned int scaler_reload;
0056 volatile unsigned int status;
0057 volatile unsigned int notused;
0058 };
0059
0060
0061
0062 static int ambapp_bus_init1(struct drvmgr_bus *bus);
0063 static int ambapp_bus_remove(struct drvmgr_bus *bus);
0064 static int ambapp_unite(struct drvmgr_drv *drv, struct drvmgr_dev *dev);
0065 static int ambapp_int_register(
0066 struct drvmgr_dev *dev,
0067 int index,
0068 const char *info,
0069 drvmgr_isr isr,
0070 void *arg);
0071 static int ambapp_int_unregister(
0072 struct drvmgr_dev *dev,
0073 int index,
0074 drvmgr_isr isr,
0075 void *arg);
0076 static int ambapp_int_clear(struct drvmgr_dev *dev, int index);
0077 static int ambapp_int_mask(struct drvmgr_dev *dev, int index);
0078 static int ambapp_int_unmask(struct drvmgr_dev *dev, int index);
0079 static int ambapp_get_params(
0080 struct drvmgr_dev *dev,
0081 struct drvmgr_bus_params *params);
0082 static int ambapp_bus_freq_get(
0083 struct drvmgr_dev *dev,
0084 int options,
0085 unsigned int *freq_hz);
0086 #ifdef AMBAPPBUS_INFO_AVAIL
0087 static void ambapp_dev_info(
0088 struct drvmgr_dev *,
0089 void (*print)(void *p, char *str),
0090 void *p);
0091 #endif
0092
0093 #ifdef RTEMS_SMP
0094 static int ambapp_int_set_affinity(
0095 struct drvmgr_dev *dev,
0096 int index,
0097 const Processor_mask *cpus);
0098 #endif
0099
0100 static struct drvmgr_bus_ops ambapp_bus_ops =
0101 {
0102 .init =
0103 {
0104 ambapp_bus_init1,
0105 NULL,
0106 NULL,
0107 NULL
0108 },
0109 .remove = ambapp_bus_remove,
0110 .unite = ambapp_unite,
0111 .int_register = ambapp_int_register,
0112 .int_unregister = ambapp_int_unregister,
0113 .int_clear = ambapp_int_clear,
0114 .int_mask = ambapp_int_mask,
0115 #ifdef RTEMS_SMP
0116 .int_set_affinity = ambapp_int_set_affinity,
0117 #endif
0118 .int_unmask = ambapp_int_unmask,
0119 .get_params = ambapp_get_params,
0120 .get_freq = ambapp_bus_freq_get,
0121 #ifdef AMBAPPBUS_INFO_AVAIL
0122 .get_info_dev = ambapp_dev_info,
0123 #endif
0124 };
0125
0126 struct ambapp_priv {
0127 struct ambapp_config *config;
0128 };
0129
0130 static int ambapp_unite(struct drvmgr_drv *drv, struct drvmgr_dev *dev)
0131 {
0132 struct amba_drv_info *adrv;
0133 struct amba_dev_id *id;
0134 struct amba_dev_info *amba;
0135
0136 if ( !drv || !dev || !dev->parent )
0137 return 0;
0138
0139 if ( ! (((drv->bus_type == DRVMGR_BUS_TYPE_AMBAPP) && (dev->parent->bus_type == DRVMGR_BUS_TYPE_AMBAPP)) ||
0140 ((drv->bus_type == DRVMGR_BUS_TYPE_AMBAPP_RMAP) && (dev->parent->bus_type == DRVMGR_BUS_TYPE_AMBAPP_RMAP)) ||
0141 ((drv->bus_type == DRVMGR_BUS_TYPE_AMBAPP_DIST) && (dev->parent->bus_type == DRVMGR_BUS_TYPE_AMBAPP_DIST)))
0142 ) {
0143 return 0;
0144 }
0145
0146 amba = (struct amba_dev_info *)dev->businfo;
0147 if ( !amba )
0148 return 0;
0149
0150 adrv = (struct amba_drv_info *)drv;
0151 id = adrv->ids;
0152 if ( !id )
0153 return 0;
0154 while( id->vendor != 0 ) {
0155 if ( (id->vendor == amba->id.vendor) &&
0156 (id->device == amba->id.device) ) {
0157
0158 DBG("DRV 0x%x and DEV 0x%x united\n", (unsigned int)drv, (unsigned int)dev);
0159 return 1;
0160 }
0161 id++;
0162 }
0163
0164 return 0;
0165 }
0166
0167 static int ambapp_int_get(struct drvmgr_dev *dev, int index)
0168 {
0169 int irq;
0170
0171
0172 if ( index >= 0 ) {
0173
0174
0175
0176 irq = ((struct amba_dev_info *)dev->businfo)->info.irq;
0177 if ( irq < 0 )
0178 return -1;
0179 irq += index;
0180 } else {
0181
0182 irq = -index;
0183 }
0184 return irq;
0185 }
0186
0187 static int ambapp_int_register(
0188 struct drvmgr_dev *dev,
0189 int index,
0190 const char *info,
0191 drvmgr_isr isr,
0192 void *arg)
0193 {
0194 struct ambapp_priv *priv;
0195 int irq;
0196
0197 priv = dev->parent->priv;
0198
0199
0200 irq = ambapp_int_get(dev, index);
0201 if ( irq < 0 )
0202 return DRVMGR_EINVAL;
0203
0204 DBG("Register interrupt on 0x%x for dev 0x%x (IRQ: %d)\n",
0205 (unsigned int)dev->parent->dev, (unsigned int)dev, irq);
0206
0207 if ( priv->config->ops->int_register ) {
0208
0209 return priv->config->ops->int_register(dev, irq, info, isr, arg);
0210 } else {
0211 return DRVMGR_ENOSYS;
0212 }
0213 }
0214
0215 static int ambapp_int_unregister(
0216 struct drvmgr_dev *dev,
0217 int index,
0218 drvmgr_isr isr,
0219 void *arg)
0220 {
0221 struct ambapp_priv *priv;
0222 int irq;
0223
0224 priv = dev->parent->priv;
0225
0226
0227 irq = ambapp_int_get(dev, index);
0228 if ( irq < 0 )
0229 return DRVMGR_EINVAL;
0230
0231 DBG("Unregister interrupt on 0x%x for dev 0x%x (IRQ: %d)\n",
0232 (unsigned int)dev->parent->dev, (unsigned int)dev, irq);
0233
0234 if ( priv->config->ops->int_unregister ) {
0235
0236 return priv->config->ops->int_unregister(dev, irq, isr, arg);
0237 } else {
0238 return DRVMGR_ENOSYS;
0239 }
0240 }
0241
0242 static int ambapp_int_clear(
0243 struct drvmgr_dev *dev,
0244 int index)
0245 {
0246 struct ambapp_priv *priv;
0247 int irq;
0248
0249 priv = dev->parent->priv;
0250
0251
0252 irq = ambapp_int_get(dev, index);
0253 if ( irq < 0 )
0254 return -1;
0255
0256 DBG("Clear interrupt on 0x%x for dev 0x%x (IRQ: %d)\n",
0257 (unsigned int)dev->parent->dev, (unsigned int)dev, irq);
0258
0259 if ( priv->config->ops->int_clear ) {
0260
0261 return priv->config->ops->int_clear(dev, irq);
0262 } else {
0263 return DRVMGR_ENOSYS;
0264 }
0265 }
0266
0267 static int ambapp_int_mask(
0268 struct drvmgr_dev *dev,
0269 int index)
0270 {
0271 struct ambapp_priv *priv;
0272 int irq;
0273
0274 priv = dev->parent->priv;
0275
0276
0277 irq = ambapp_int_get(dev, index);
0278 if ( irq < 0 )
0279 return -1;
0280
0281 DBG("MASK interrupt on 0x%x for dev 0x%x (IRQ: %d)\n",
0282 (unsigned int)dev->parent->dev, (unsigned int)dev, irq);
0283
0284 if ( priv->config->ops->int_mask ) {
0285
0286 return priv->config->ops->int_mask(dev, irq);
0287 } else {
0288 return DRVMGR_ENOSYS;
0289 }
0290 }
0291
0292 static int ambapp_int_unmask(
0293 struct drvmgr_dev *dev,
0294 int index)
0295 {
0296 struct ambapp_priv *priv;
0297 int irq;
0298
0299 priv = dev->parent->priv;
0300
0301
0302 irq = ambapp_int_get(dev, index);
0303 if ( irq < 0 )
0304 return DRVMGR_EINVAL;
0305
0306 DBG("UNMASK interrupt on 0x%x for dev 0x%x (IRQ: %d)\n",
0307 (unsigned int)dev->parent->dev, (unsigned int)dev, irq);
0308
0309 if ( priv->config->ops->int_unmask ) {
0310
0311 return priv->config->ops->int_unmask(dev, irq);
0312 } else {
0313 return DRVMGR_ENOSYS;
0314 }
0315 }
0316
0317
0318 void ambapp_bus_freq_register(
0319 struct drvmgr_dev *dev,
0320 int amba_interface,
0321 unsigned int freq_hz
0322 )
0323 {
0324 struct ambapp_priv *priv = (struct ambapp_priv *)dev->parent->priv;
0325 struct ambapp_dev *adev;
0326 struct amba_dev_info *pnp = dev->businfo;
0327
0328 if ( freq_hz == 0 )
0329 return;
0330
0331 if ( amba_interface == DEV_AHB_MST ) {
0332 adev = (struct ambapp_dev *)
0333 ((unsigned int)pnp->info.ahb_mst -
0334 sizeof(struct ambapp_dev));
0335 } else if ( amba_interface == DEV_AHB_SLV ) {
0336 adev = (struct ambapp_dev *)
0337 ((unsigned int)pnp->info.ahb_slv -
0338 sizeof(struct ambapp_dev));
0339 } else if ( amba_interface == DEV_APB_SLV ) {
0340 adev = (struct ambapp_dev *)
0341 ((unsigned int)pnp->info.apb_slv -
0342 sizeof(struct ambapp_dev));
0343 } else {
0344 return;
0345 }
0346
0347
0348
0349
0350 ambapp_freq_init(priv->config->abus, adev, freq_hz);
0351 }
0352
0353 static int ambapp_bus_freq_get(
0354 struct drvmgr_dev *dev,
0355 int options,
0356 unsigned int *freq_hz)
0357 {
0358 struct ambapp_priv *priv = (struct ambapp_priv *)dev->parent->priv;
0359 struct ambapp_dev *adev;
0360 struct amba_dev_info *pnp = dev->businfo;
0361
0362 if ( options == DEV_AHB_MST ) {
0363 adev = (struct ambapp_dev *)
0364 ((unsigned int)pnp->info.ahb_mst -
0365 sizeof(struct ambapp_dev));
0366 } else if ( options == DEV_AHB_SLV ) {
0367 adev = (struct ambapp_dev *)
0368 ((unsigned int)pnp->info.ahb_slv -
0369 sizeof(struct ambapp_dev));
0370 } else if ( options == DEV_APB_SLV ) {
0371 adev = (struct ambapp_dev *)
0372 ((unsigned int)pnp->info.apb_slv -
0373 sizeof(struct ambapp_dev));
0374 } else {
0375 *freq_hz = 0;
0376 return -1;
0377 }
0378
0379
0380 *freq_hz = ambapp_freq_get(priv->config->abus, adev);
0381 if ( *freq_hz == 0 )
0382 return -1;
0383 return 0;
0384 }
0385
0386 static int ambapp_get_params(
0387 struct drvmgr_dev *dev,
0388 struct drvmgr_bus_params *params)
0389 {
0390 struct ambapp_priv *priv = dev->parent->priv;
0391
0392 if ( priv->config->ops->get_params ) {
0393
0394 return priv->config->ops->get_params(dev, params);
0395 } else {
0396 return -1;
0397 }
0398 }
0399
0400 #ifdef AMBAPPBUS_INFO_AVAIL
0401 static void ambapp_dev_info(
0402 struct drvmgr_dev *dev,
0403 void (*print_line)(void *p, char *str),
0404 void *p)
0405 {
0406 struct amba_dev_info *devinfo;
0407 struct ambapp_core *core;
0408 char buf[64];
0409 int ver, i;
0410 char *str1, *str2, *str3;
0411 unsigned int ahbmst_freq, ahbslv_freq, apbslv_freq;
0412
0413 if (!dev)
0414 return;
0415
0416 devinfo = (struct amba_dev_info *)dev->businfo;
0417 if (!devinfo)
0418 return;
0419 core = &devinfo->info;
0420
0421 print_line(p, "AMBA PnP DEVICE");
0422
0423 str1 = ambapp_vendor_id2str(devinfo->id.vendor);
0424 if (str1 == NULL)
0425 str1 = "unknown";
0426 sprintf(buf, "VENDOR ID: 0x%04x (%s)", devinfo->id.vendor, str1);
0427 print_line(p, buf);
0428
0429 str1 = ambapp_device_id2str(devinfo->id.vendor, devinfo->id.device);
0430 if (str1 == NULL)
0431 str1 = "unknown";
0432 sprintf(buf, "DEVICE ID: 0x%04x (%s)", devinfo->id.device, str1);
0433 print_line(p, buf);
0434
0435 ahbmst_freq = ahbslv_freq = apbslv_freq = 0;
0436 ver = 0;
0437 str1 = str2 = str3 = "";
0438 if (core->ahb_mst) {
0439 str1 = "AHBMST ";
0440 ver = core->ahb_mst->common.ver;
0441 ambapp_bus_freq_get(dev, DEV_AHB_MST, &ahbmst_freq);
0442 }
0443 if (core->ahb_slv) {
0444 str2 = "AHBSLV ";
0445 ver = core->ahb_slv->common.ver;
0446 ambapp_bus_freq_get(dev, DEV_AHB_SLV, &ahbslv_freq);
0447 }
0448 if (core->apb_slv) {
0449 str3 = "APBSLV";
0450 ver = core->apb_slv->common.ver;
0451 ambapp_bus_freq_get(dev, DEV_APB_SLV, &apbslv_freq);
0452 }
0453
0454 sprintf(buf, "IRQ: %d", ambapp_int_get(dev, 0));
0455 print_line(p, buf);
0456
0457 sprintf(buf, "VERSION: 0x%x", ver);
0458 print_line(p, buf);
0459
0460 sprintf(buf, "ambapp_core: %p", core);
0461 print_line(p, buf);
0462
0463 sprintf(buf, "interfaces: %s%s%s", str1, str2, str3);
0464 print_line(p, buf);
0465
0466 if (ahbmst_freq != 0) {
0467 sprintf(buf, "AHBMST FREQ: %dkHz", ahbmst_freq/1000);
0468 print_line(p, buf);
0469 }
0470
0471 if (ahbslv_freq != 0) {
0472 sprintf(buf, "AHBSLV FREQ: %dkHz", ahbslv_freq/1000);
0473 print_line(p, buf);
0474 }
0475
0476 if (apbslv_freq != 0) {
0477 sprintf(buf, "APBSLV FREQ: %dkHz", apbslv_freq/1000);
0478 print_line(p, buf);
0479 }
0480
0481 if (core->ahb_slv) {
0482 for(i=0; i<4; i++) {
0483 if (core->ahb_slv->type[i] == AMBA_TYPE_AHBIO)
0484 str1 = " ahbio";
0485 else if (core->ahb_slv->type[i] == AMBA_TYPE_MEM)
0486 str1 = "ahbmem";
0487 else
0488 continue;
0489 sprintf(buf, " %s[%d]: 0x%08x-0x%08x", str1, i,
0490 core->ahb_slv->start[i],
0491 core->ahb_slv->start[i]+core->ahb_slv->mask[i]-1);
0492 print_line(p, buf);
0493 }
0494 }
0495 if (core->apb_slv) {
0496 sprintf(buf, " apb: 0x%08x-0x%08x",
0497 core->apb_slv->start,
0498 core->apb_slv->start + core->apb_slv->mask - 1);
0499 print_line(p, buf);
0500 }
0501 }
0502 #endif
0503
0504
0505
0506
0507
0508
0509 static int ambapp_dev_fixup(struct drvmgr_dev *dev, struct amba_dev_info *pnp)
0510 {
0511
0512
0513
0514
0515
0516
0517
0518
0519 if ( (pnp->info.device == GAISLER_CANAHB) &&
0520 (pnp->info.vendor == VENDOR_GAISLER) ) {
0521 struct drvmgr_dev *newdev, *devs_to_register[8];
0522 struct amba_dev_info *pnpinfo;
0523 int subcores;
0524 int core;
0525
0526 devs_to_register[0] = dev;
0527 subcores = (pnp->info.ahb_slv->common.ver & 0x7) + 1;
0528 for(core = 1; core < subcores; core++) {
0529 drvmgr_alloc_dev(&newdev, sizeof(*pnpinfo));
0530 memcpy(newdev, dev, sizeof(*newdev));
0531 pnpinfo = (struct amba_dev_info *)(newdev+1);
0532 memcpy(pnpinfo, pnp, sizeof(*pnp));
0533 pnpinfo->info.index = core;
0534 pnpinfo->info.irq += core;
0535 newdev->businfo = (void *)pnpinfo;
0536
0537 devs_to_register[core] = newdev;
0538 }
0539
0540 for(core = 0; core < subcores; core++)
0541 drvmgr_dev_register(devs_to_register[core]);
0542 return 1;
0543 } else if ( (pnp->info.device == GAISLER_GPIO) &&
0544 (pnp->info.vendor == VENDOR_GAISLER) ) {
0545
0546 pnp->info.irq = 0;
0547 }
0548 return 0;
0549 }
0550
0551 struct ambapp_dev_reg_struct {
0552 struct ambapp_bus *abus;
0553 struct drvmgr_bus *bus;
0554 struct ambapp_dev *ahb_mst;
0555 struct ambapp_dev *ahb_slv;
0556 struct ambapp_dev *apb_slv;
0557 };
0558
0559 static void ambapp_core_register(
0560 struct ambapp_dev *ahb_mst,
0561 struct ambapp_dev *ahb_slv,
0562 struct ambapp_dev *apb_slv,
0563 struct ambapp_dev_reg_struct *arg
0564 )
0565 {
0566 struct drvmgr_dev *newdev;
0567 struct amba_dev_info *pnpinfo;
0568 unsigned short device;
0569 unsigned char vendor;
0570 int namelen;
0571 char buf[64];
0572
0573 if ( ahb_mst ) {
0574 device = ahb_mst->device;
0575 vendor = ahb_mst->vendor;
0576 }else if ( ahb_slv ) {
0577 device = ahb_slv->device;
0578 vendor = ahb_slv->vendor;
0579 }else if( apb_slv ) {
0580 device = apb_slv->device;
0581 vendor = apb_slv->vendor;
0582 } else {
0583 DBG("NO DEV!\n");
0584 return;
0585 }
0586
0587 DBG("CORE REGISTER DEV [%x:%x] MST: 0x%x, SLV: 0x%x, APB: 0x%x\n", vendor, device, (unsigned int)ahb_mst, (unsigned int)ahb_slv, (unsigned int)apb_slv);
0588
0589
0590
0591
0592 namelen = ambapp_vendev_id2str(vendor, device, buf);
0593
0594
0595 drvmgr_alloc_dev(&newdev, sizeof(struct amba_dev_info) + namelen);
0596 pnpinfo = (struct amba_dev_info *)(newdev + 1);
0597 newdev->parent = arg->bus;
0598 newdev->minor_drv = 0;
0599 newdev->minor_bus = 0;
0600 newdev->priv = NULL;
0601 newdev->drv = NULL;
0602 if (namelen > 0) {
0603 newdev->name = (char *)(pnpinfo + 1);
0604 strcpy(newdev->name, buf);
0605 } else {
0606 newdev->name = NULL;
0607 }
0608 newdev->next_in_drv = NULL;
0609 newdev->bus = NULL;
0610
0611
0612 pnpinfo->id.vendor = vendor;
0613 pnpinfo->id.device = device;
0614 pnpinfo->info.vendor = vendor;
0615 pnpinfo->info.device = device;
0616 pnpinfo->info.index = 0;
0617 if ( ahb_mst ) {
0618 pnpinfo->info.ahb_mst = (struct ambapp_ahb_info *)
0619 ahb_mst->devinfo;
0620 ambapp_alloc_dev(ahb_mst, (void *)newdev);
0621 if ( pnpinfo->info.ahb_mst->common.irq )
0622 pnpinfo->info.irq = pnpinfo->info.ahb_mst->common.irq;
0623 }
0624 if ( ahb_slv ) {
0625 pnpinfo->info.ahb_slv = (struct ambapp_ahb_info *)
0626 ahb_slv->devinfo;
0627 ambapp_alloc_dev(ahb_slv, (void *)newdev);
0628 if ( pnpinfo->info.ahb_slv->common.irq )
0629 pnpinfo->info.irq = pnpinfo->info.ahb_slv->common.irq;
0630 }
0631 if ( apb_slv ) {
0632 pnpinfo->info.apb_slv = (struct ambapp_apb_info *)
0633 apb_slv->devinfo;
0634 ambapp_alloc_dev(apb_slv, (void *)newdev);
0635 if ( pnpinfo->info.apb_slv->common.irq )
0636 pnpinfo->info.irq = pnpinfo->info.apb_slv->common.irq;
0637 }
0638 if ( pnpinfo->info.irq == 0 )
0639 pnpinfo->info.irq = -1;
0640
0641
0642 newdev->businfo = (void *)pnpinfo;
0643
0644 if ( ambapp_dev_fixup(newdev, pnpinfo) == 0 )
0645 drvmgr_dev_register(newdev);
0646 }
0647
0648
0649
0650
0651
0652
0653 static int ambapp_dev_register_fixup(struct ambapp_dev *dev, struct ambapp_dev_reg_struct *p)
0654 {
0655
0656
0657
0658
0659 if ( (dev->dev_type == DEV_APB_SLV) &&
0660 (dev->device == GAISLER_GRPCI2) &&
0661 (dev->vendor == VENDOR_GAISLER) &&
0662 (p->ahb_slv == NULL) ) {
0663 DBG("GRPCI2 APB_SLV detected before AHB_SLV. Skipping APB_SLV registration.\n");
0664 return 1;
0665 }
0666 return 0;
0667 }
0668
0669
0670 static int ambapp_dev_register(struct ambapp_dev *dev, int index, void *arg)
0671 {
0672 struct ambapp_dev_reg_struct *p = arg;
0673
0674 #ifdef DEBUG
0675 char *type;
0676
0677 if ( dev->dev_type == DEV_AHB_MST )
0678 type = "AHB MST";
0679 else if ( dev->dev_type == DEV_AHB_SLV )
0680 type = "AHB SLV";
0681 else if ( dev->dev_type == DEV_APB_SLV )
0682 type = "APB SLV";
0683
0684 DBG("Found [%d:%x:%x], %s\n", index, dev->vendor, dev->device, type);
0685 #endif
0686
0687
0688 if (ambapp_dev_register_fixup(dev, p)){
0689 return 0;
0690 }
0691
0692 if ( dev->dev_type == DEV_AHB_MST ) {
0693 if ( p->ahb_mst ) {
0694
0695 printk("ambapp_dev_register: ahb_mst not NULL!\n");
0696 exit(1);
0697 }
0698
0699
0700 p->ahb_mst = dev;
0701
0702
0703 ambapp_for_each(p->abus, (OPTIONS_AHB_SLVS|OPTIONS_APB_SLVS|OPTIONS_FREE), dev->vendor, dev->device, ambapp_dev_register, p);
0704
0705 ambapp_core_register(p->ahb_mst, p->ahb_slv, p->apb_slv, p);
0706 p->ahb_mst = p->ahb_slv = p->apb_slv = NULL;
0707 return 0;
0708
0709 } else if ( dev->dev_type == DEV_AHB_SLV ) {
0710 if ( p->ahb_slv ) {
0711
0712 return 0;
0713 }
0714
0715
0716 p->ahb_slv = dev;
0717
0718 if ( p->ahb_mst ) {
0719
0720 return 0;
0721 } else {
0722
0723 ambapp_for_each(p->abus, (OPTIONS_APB_SLVS|OPTIONS_FREE), dev->vendor, dev->device, ambapp_dev_register, p);
0724
0725 ambapp_core_register(p->ahb_mst, p->ahb_slv, p->apb_slv, p);
0726 p->ahb_mst = p->ahb_slv = p->apb_slv = NULL;
0727 return 0;
0728 }
0729 } else if ( dev->dev_type == DEV_APB_SLV ) {
0730 if ( p->apb_slv ) {
0731
0732 printk("ambapp_dev_register: apb_slv not NULL!\n");
0733 exit(1);
0734 }
0735
0736 p->apb_slv = dev;
0737
0738 if ( p->ahb_mst || p->ahb_slv ) {
0739
0740 return 1;
0741 } else {
0742 ambapp_core_register(p->ahb_mst, p->ahb_slv, p->apb_slv, p);
0743 p->ahb_mst = p->ahb_slv = p->apb_slv = NULL;
0744 return 0;
0745 }
0746 }
0747
0748 return 0;
0749 }
0750
0751
0752 static int ambapp_ids_register(struct drvmgr_bus *bus)
0753 {
0754 struct ambapp_priv *priv = bus->priv;
0755 struct ambapp_bus *abus;
0756 struct ambapp_dev_reg_struct arg;
0757
0758 DBG("ambapp_ids_register:\n");
0759
0760 memset(&arg, 0, sizeof(arg));
0761
0762 abus = priv->config->abus;
0763 arg.abus = abus;
0764 arg.bus = bus;
0765
0766
0767
0768
0769 ambapp_for_each(abus, (OPTIONS_ALL_DEVS|OPTIONS_FREE), -1, -1, ambapp_dev_register, &arg);
0770
0771 #ifdef DEBUG
0772 ambapp_print(abus->root, 1);
0773 #endif
0774
0775 return DRVMGR_OK;
0776 }
0777
0778
0779
0780 int ambapp_bus_register(struct drvmgr_dev *dev, struct ambapp_config *config)
0781 {
0782 struct ambapp_priv *priv;
0783
0784 if ( !config || !config->ops )
0785 return DRVMGR_OK;
0786
0787 DBG("AMBAPP BUS: initializing\n");
0788
0789
0790 drvmgr_alloc_bus(&dev->bus, sizeof(struct ambapp_priv));
0791 priv = (struct ambapp_priv *)(dev->bus + 1);
0792 priv->config = config;
0793 if ( priv->config->bus_type == DRVMGR_BUS_TYPE_AMBAPP_DIST )
0794 dev->bus->bus_type = DRVMGR_BUS_TYPE_AMBAPP_DIST;
0795 else if ( priv->config->bus_type == DRVMGR_BUS_TYPE_AMBAPP_RMAP )
0796 dev->bus->bus_type = DRVMGR_BUS_TYPE_AMBAPP_RMAP;
0797 else
0798 dev->bus->bus_type = DRVMGR_BUS_TYPE_AMBAPP;
0799 dev->bus->next = NULL;
0800 dev->bus->dev = dev;
0801 dev->bus->priv = priv;
0802 dev->bus->children = NULL;
0803 dev->bus->ops = &ambapp_bus_ops;
0804 dev->bus->funcs = config->funcs;
0805 dev->bus->dev_cnt = 0;
0806 dev->bus->reslist = NULL;
0807 dev->bus->maps_up = config->maps_up;
0808 dev->bus->maps_down = config->maps_down;
0809
0810
0811 if ( priv->config->resources )
0812 drvmgr_bus_res_add(dev->bus, priv->config->resources);
0813
0814 drvmgr_bus_register(dev->bus);
0815
0816 return DRVMGR_OK;
0817 }
0818
0819
0820
0821
0822 static int ambapp_bus_init1(struct drvmgr_bus *bus)
0823 {
0824
0825 return ambapp_ids_register(bus);
0826 }
0827
0828 static int ambapp_bus_remove(struct drvmgr_bus *bus)
0829 {
0830 return DRVMGR_OK;
0831 }
0832
0833 #ifdef RTEMS_SMP
0834 static int ambapp_int_set_affinity(
0835 struct drvmgr_dev *dev,
0836 int index,
0837 const Processor_mask *cpus)
0838 {
0839 struct ambapp_priv *priv;
0840 int irq;
0841
0842 priv = dev->parent->priv;
0843
0844
0845 irq = ambapp_int_get(dev, index);
0846 if (irq < 0)
0847 return DRVMGR_EINVAL;
0848
0849 DBG("Set interrupt affinity on 0x%x for dev 0x%x (IRQ: %d)\n",
0850 (unsigned int)dev->parent->dev, (unsigned int)dev, irq);
0851
0852 if (priv->config->ops->int_set_affinity) {
0853
0854 return priv->config->ops->int_set_affinity(dev, irq, cpus);
0855 } else {
0856 return DRVMGR_ENOSYS;
0857 }
0858 }
0859 #endif