int main(int argc, char *argv[]) { int mb = -1; uint32_t gvp = NULL; unsigned *addr = NULL; unsigned off; int val; if (argc != 2) { fprintf(stderr, "error: Invalid the number of the arguments\n"); usage(argv[0]); exit(EXIT_FAILURE); } off = 0; /* 0 is for the activity LED. */ val = atoi(argv[1]); mb = rpi_firmware_open(); rpi_firmware_property(mb, RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF, &gvp, sizeof(gvp)); addr = mapmem_cpu(BUS_TO_PHYS(gvp), 4096); gpio_set(addr, off, val); unmapmem_cpu(addr, 4096); addr = NULL; rpi_firmware_close(mb); mb = -1; return 0; }
/* * Asks the firmware to enable or disable power on a specific power * domain. */ static int rpi_firmware_set_power(struct rpi_power_domain *rpi_domain, bool on) { struct rpi_power_domain_packet packet; packet.domain = rpi_domain->domain; packet.on = on; return rpi_firmware_property(rpi_domain->fw, rpi_domain->old_interface ? RPI_FIRMWARE_SET_POWER_STATE : RPI_FIRMWARE_SET_DOMAIN_STATE, &packet, sizeof(packet)); }
/* * Detects whether the firmware supports the new power domains interface. * * The firmware doesn't actually return an error on an unknown tag, * and just skips over it, so we do the detection by putting an * unexpected value in the return field and checking if it was * unchanged. */ static bool rpi_has_new_domain_support(struct rpi_power_domains *rpi_domains) { struct rpi_power_domain_packet packet; int ret; packet.domain = RPI_POWER_DOMAIN_ARM; packet.on = ~0; ret = rpi_firmware_property(rpi_domains->fw, RPI_FIRMWARE_GET_DOMAIN_STATE, &packet, sizeof(packet)); return ret == 0 && packet.on != ~0; }
static int bcm2835_cpufreq_clock_property(u32 tag, u32 id, u32 *val) { struct rpi_firmware *fw = rpi_firmware_get(NULL); struct { u32 id; u32 val; } packet; int ret; packet.id = id; packet.val = *val; ret = rpi_firmware_property(fw, tag, &packet, sizeof(packet)); if (ret) return ret; *val = packet.val; return 0; }
static int bcm2835_thermal_get_property(struct thermal_zone_device *tz, unsigned long *temp, u32 tag) { struct rpi_firmware *fw = tz->devdata; struct { u32 id; u32 val; } packet; int ret; *temp = 0; packet.id = 0; ret = rpi_firmware_property(fw, tag, &packet, sizeof(packet)); if (ret) { dev_err(&tz->device, "Failed to get temperature\n"); return ret; } *temp = packet.val; dev_dbg(&tz->device, "%stemp=%lu\n", tag == RPI_FIRMWARE_GET_MAX_TEMPERATURE ? "max" : "", *temp); return 0; }
int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) { struct device *dev = &pdev->dev; struct rpi_firmware *fw = platform_get_drvdata(pdev); VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; struct resource *res; void *slot_mem; dma_addr_t slot_phys; u32 channelbase; int slot_mem_size, frag_mem_size; int err, irq, i; g_virt_to_bus_offset = virt_to_dma(dev, (void *)0); (void)of_property_read_u32(dev->of_node, "cache-line-size", &g_cache_line_size); g_fragments_size = 2 * g_cache_line_size; /* Allocate space for the channels in coherent memory */ slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); frag_mem_size = PAGE_ALIGN(g_fragments_size * MAX_FRAGMENTS); slot_mem = dmam_alloc_coherent(dev, slot_mem_size + frag_mem_size, &slot_phys, GFP_KERNEL); if (!slot_mem) { dev_err(dev, "could not allocate DMA memory\n"); return -ENOMEM; } WARN_ON(((int)slot_mem & (PAGE_SIZE - 1)) != 0); vchiq_slot_zero = vchiq_init_slots(slot_mem, slot_mem_size); if (!vchiq_slot_zero) return -EINVAL; vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX] = (int)slot_phys + slot_mem_size; vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = MAX_FRAGMENTS; g_fragments_base = (char *)slot_mem + slot_mem_size; slot_mem_size += frag_mem_size; g_free_fragments = g_fragments_base; for (i = 0; i < (MAX_FRAGMENTS - 1); i++) { *(char **)&g_fragments_base[i*g_fragments_size] = &g_fragments_base[(i + 1)*g_fragments_size]; } *(char **)&g_fragments_base[i * g_fragments_size] = NULL; sema_init(&g_free_fragments_sema, MAX_FRAGMENTS); if (vchiq_init_state(state, vchiq_slot_zero, 0) != VCHIQ_SUCCESS) return -EINVAL; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); g_regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(g_regs)) return PTR_ERR(g_regs); irq = platform_get_irq(pdev, 0); if (irq <= 0) { dev_err(dev, "failed to get IRQ\n"); return irq; } err = devm_request_irq(dev, irq, vchiq_doorbell_irq, IRQF_IRQPOLL, "VCHIQ doorbell", state); if (err) { dev_err(dev, "failed to register irq=%d\n", irq); return err; } /* Send the base address of the slots to VideoCore */ channelbase = slot_phys; err = rpi_firmware_property(fw, RPI_FIRMWARE_VCHIQ_INIT, &channelbase, sizeof(channelbase)); if (err || channelbase) { dev_err(dev, "failed to set channelbase\n"); return err ? : -ENXIO; }