static struct device_t * gpio_bcm2836_virt_probe(struct driver_t * drv, struct dtnode_t * n) { struct gpio_bcm2836_virt_pdata_t * pdat; struct gpiochip_t * chip; struct device_t * dev; int base = dt_read_int(n, "gpio-base", -1); int ngpio = dt_read_int(n, "gpio-count", -1); if((base < 0) || (ngpio <= 0)) return NULL; pdat = malloc(sizeof(struct gpio_bcm2836_virt_pdata_t)); if(!pdat) return NULL; chip = malloc(sizeof(struct gpiochip_t)); if(!chip) { free(pdat); return NULL; } pdat->base = base; pdat->ngpio = ngpio; pdat->oirq = dt_read_int(n, "interrupt-offset", -1); pdat->virtbuf = bcm2836_mbox_fb_get_gpiovirt(); pdat->status = malloc(sizeof(uint32_t) * pdat->ngpio); memset(pdat->status, 0, sizeof(uint32_t) * pdat->ngpio); chip->name = alloc_device_name(dt_read_name(n), -1); chip->base = pdat->base; chip->ngpio = pdat->ngpio; chip->set_cfg = gpio_bcm2836_virt_set_cfg; chip->get_cfg = gpio_bcm2836_virt_get_cfg; chip->set_pull = gpio_bcm2836_virt_set_pull; chip->get_pull = gpio_bcm2836_virt_get_pull; chip->set_drv = gpio_bcm2836_virt_set_drv; chip->get_drv = gpio_bcm2836_virt_get_drv; chip->set_rate = gpio_bcm2836_virt_set_rate; chip->get_rate = gpio_bcm2836_virt_get_rate; chip->set_dir = gpio_bcm2836_virt_set_dir; chip->get_dir = gpio_bcm2836_virt_get_dir; chip->set_value = gpio_bcm2836_virt_set_value; chip->get_value = gpio_bcm2836_virt_get_value; chip->to_irq = gpio_bcm2836_virt_to_irq; chip->priv = pdat; if(!register_gpiochip(&dev, chip)) { free(pdat->status); free_device_name(chip->name); free(chip->priv); free(chip); return NULL; } dev->driver = drv; return dev; }
static struct device_t * gpio_pl061_probe(struct driver_t * drv, struct dtnode_t * n) { struct gpio_pl061_pdata_t * pdat; struct gpiochip_t * chip; struct device_t * dev; virtual_addr_t virt = phys_to_virt(dt_read_address(n)); u32_t id = (((read32(virt + 0xfec) & 0xff) << 24) | ((read32(virt + 0xfe8) & 0xff) << 16) | ((read32(virt + 0xfe4) & 0xff) << 8) | ((read32(virt + 0xfe0) & 0xff) << 0)); int base = dt_read_int(n, "gpio-base", -1); int ngpio = dt_read_int(n, "gpio-count", -1); if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x061) return NULL; if((base < 0) || (ngpio <= 0)) return NULL; pdat = malloc(sizeof(struct gpio_pl061_pdata_t)); if(!pdat) return NULL; chip = malloc(sizeof(struct gpiochip_t)); if(!chip) { free(pdat); return NULL; } pdat->virt = virt; pdat->base = base; pdat->ngpio = ngpio; pdat->oirq = dt_read_int(n, "interrupt-offset", -1); chip->name = alloc_device_name(dt_read_name(n), -1); chip->base = pdat->base; chip->ngpio = pdat->ngpio; chip->set_cfg = gpio_pl061_set_cfg; chip->get_cfg = gpio_pl061_get_cfg; chip->set_pull = gpio_pl061_set_pull; chip->get_pull = gpio_pl061_get_pull; chip->set_drv = gpio_pl061_set_drv; chip->get_drv = gpio_pl061_get_drv; chip->set_rate = gpio_pl061_set_rate; chip->get_rate = gpio_pl061_get_rate; chip->set_dir = gpio_pl061_set_dir; chip->get_dir = gpio_pl061_get_dir; chip->set_value = gpio_pl061_set_value; chip->get_value = gpio_pl061_get_value; chip->to_irq = gpio_pl061_to_irq; chip->priv = pdat; if(!register_gpiochip(&dev, chip)) { free_device_name(chip->name); free(chip->priv); free(chip); return NULL; } dev->driver = drv; return dev; }