447 lines
14 KiB
Diff
447 lines
14 KiB
Diff
From 37fd085e3449fabd2d976d671ebf2a6c631c9afd Mon Sep 17 00:00:00 2001
|
|
From: Phil Elwell <phil@raspberrypi.org>
|
|
Date: Mon, 1 Sep 2014 16:35:56 +0100
|
|
Subject: [PATCH 063/114] bcm2708: Allow option card devices to be configured
|
|
via DT
|
|
|
|
If the kernel is built with Device Tree support, and if a DT blob
|
|
is provided for the kernel at boot time, then the platform devices
|
|
for option cards are not created. This avoids both the need to
|
|
blacklist unwanted devices, and the need to update the board
|
|
support code with each new device.
|
|
---
|
|
arch/arm/mach-bcm2708/bcm2708.c | 70 ++++++++++++++++++++---------------------
|
|
drivers/dma/bcm2708-dmaengine.c | 14 ++++-----
|
|
drivers/mmc/host/bcm2835-mmc.c | 24 +++++++-------
|
|
drivers/of/fdt.c | 6 +++-
|
|
sound/soc/bcm/bcm2708-i2s.c | 29 +++++++++++------
|
|
sound/soc/bcm/bcm2835-i2s.c | 1 +
|
|
6 files changed, 80 insertions(+), 64 deletions(-)
|
|
|
|
--- a/arch/arm/mach-bcm2708/bcm2708.c
|
|
+++ b/arch/arm/mach-bcm2708/bcm2708.c
|
|
@@ -35,6 +35,7 @@
|
|
#include <linux/module.h>
|
|
#include <linux/of_platform.h>
|
|
#include <linux/spi/spi.h>
|
|
+#include <linux/gpio/machine.h>
|
|
#include <linux/w1-gpio.h>
|
|
|
|
#include <linux/version.h>
|
|
@@ -93,6 +94,8 @@ static unsigned reboot_part = 0;
|
|
static unsigned w1_gpio_pin = W1_GPIO;
|
|
static unsigned w1_gpio_pullup = W1_PULLUP;
|
|
|
|
+static unsigned use_dt = 0;
|
|
+
|
|
static void __init bcm2708_init_led(void);
|
|
|
|
void __init bcm2708_init_irq(void)
|
|
@@ -514,7 +517,6 @@ static struct platform_device bcm2708_al
|
|
},
|
|
};
|
|
|
|
-#ifndef CONFIG_OF
|
|
static struct resource bcm2708_spi_resources[] = {
|
|
{
|
|
.start = SPI0_BASE,
|
|
@@ -538,7 +540,6 @@ static struct platform_device bcm2708_sp
|
|
.dma_mask = &bcm2708_spi_dmamask,
|
|
.coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON)},
|
|
};
|
|
-#endif
|
|
|
|
#ifdef CONFIG_BCM2708_SPIDEV
|
|
static struct spi_board_info bcm2708_spi_devices[] = {
|
|
@@ -560,7 +561,6 @@ static struct spi_board_info bcm2708_spi
|
|
};
|
|
#endif
|
|
|
|
-#ifndef CONFIG_OF
|
|
static struct resource bcm2708_bsc0_resources[] = {
|
|
{
|
|
.start = BSC0_BASE,
|
|
@@ -599,7 +599,6 @@ static struct platform_device bcm2708_bs
|
|
.num_resources = ARRAY_SIZE(bcm2708_bsc1_resources),
|
|
.resource = bcm2708_bsc1_resources,
|
|
};
|
|
-#endif
|
|
|
|
static struct platform_device bcm2835_hwmon_device = {
|
|
.name = "bcm2835_hwmon",
|
|
@@ -609,7 +608,7 @@ static struct platform_device bcm2835_th
|
|
.name = "bcm2835_thermal",
|
|
};
|
|
|
|
-#ifdef CONFIG_SND_BCM2708_SOC_I2S_MODULE
|
|
+#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE)
|
|
static struct resource bcm2708_i2s_resources[] = {
|
|
{
|
|
.start = I2S_BASE,
|
|
@@ -731,14 +730,14 @@ int __init bcm_register_device(struct pl
|
|
}
|
|
|
|
/*
|
|
- * Use this macro for platform devices that are present in the Device Tree.
|
|
- * This way the device is only added on non-DT builds.
|
|
+ * Use these macros for platform and i2c devices that are present in the
|
|
+ * Device Tree. This way the devices are only added on non-DT systems.
|
|
*/
|
|
-#ifdef CONFIG_OF
|
|
-#define bcm_register_device_dt(pdev)
|
|
-#else
|
|
-#define bcm_register_device_dt(pdev) bcm_register_device(pdev)
|
|
-#endif
|
|
+#define bcm_register_device_dt(pdev) \
|
|
+ if (!use_dt) bcm_register_device(pdev)
|
|
+
|
|
+#define i2c_register_board_info_dt(busnum, info, n) \
|
|
+ if (!use_dt) i2c_register_board_info(busnum, info, n)
|
|
|
|
int calc_rsts(int partition)
|
|
{
|
|
@@ -814,7 +813,9 @@ static void __init bcm2708_dt_init(void)
|
|
ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
|
if (ret) {
|
|
pr_err("of_platform_populate failed: %d\n", ret);
|
|
- BUG();
|
|
+ /* Proceed as if CONFIG_OF was not defined */
|
|
+ } else {
|
|
+ use_dt = 1;
|
|
}
|
|
}
|
|
#else
|
|
@@ -842,7 +843,7 @@ void __init bcm2708_init(void)
|
|
#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
|
|
w1_gpio_pdata.pin = w1_gpio_pin;
|
|
w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup;
|
|
- platform_device_register(&w1_device);
|
|
+ bcm_register_device_dt(&w1_device);
|
|
#endif
|
|
bcm_register_device(&bcm2708_systemtimer_device);
|
|
bcm_register_device(&bcm2708_fb_device);
|
|
@@ -857,46 +858,45 @@ void __init bcm2708_init(void)
|
|
for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++)
|
|
bcm_register_device(&bcm2708_alsa_devices[i]);
|
|
|
|
+ bcm_register_device(&bcm2835_hwmon_device);
|
|
+ bcm_register_device(&bcm2835_thermal_device);
|
|
+
|
|
bcm_register_device_dt(&bcm2708_spi_device);
|
|
bcm_register_device_dt(&bcm2708_bsc0_device);
|
|
bcm_register_device_dt(&bcm2708_bsc1_device);
|
|
|
|
- bcm_register_device(&bcm2835_hwmon_device);
|
|
- bcm_register_device(&bcm2835_thermal_device);
|
|
-
|
|
-#ifdef CONFIG_SND_BCM2708_SOC_I2S_MODULE
|
|
- bcm_register_device(&bcm2708_i2s_device);
|
|
+#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE)
|
|
+ bcm_register_device_dt(&bcm2708_i2s_device);
|
|
#endif
|
|
|
|
#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE)
|
|
- bcm_register_device(&snd_hifiberry_dac_device);
|
|
- bcm_register_device(&snd_pcm5102a_codec_device);
|
|
+ bcm_register_device_dt(&snd_hifiberry_dac_device);
|
|
+ bcm_register_device_dt(&snd_pcm5102a_codec_device);
|
|
#endif
|
|
|
|
#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE)
|
|
- bcm_register_device(&snd_rpi_hifiberry_dacplus_device);
|
|
- i2c_register_board_info(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices));
|
|
+ bcm_register_device_dt(&snd_rpi_hifiberry_dacplus_device);
|
|
+ i2c_register_board_info_dt(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices));
|
|
#endif
|
|
|
|
#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE)
|
|
- bcm_register_device(&snd_hifiberry_digi_device);
|
|
- i2c_register_board_info(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices));
|
|
+ bcm_register_device_dt(&snd_hifiberry_digi_device);
|
|
+ i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices));
|
|
#endif
|
|
|
|
#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE)
|
|
- bcm_register_device(&snd_hifiberry_amp_device);
|
|
- i2c_register_board_info(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices));
|
|
+ bcm_register_device_dt(&snd_hifiberry_amp_device);
|
|
+ i2c_register_board_info_dt(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices));
|
|
#endif
|
|
|
|
-
|
|
#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE)
|
|
- bcm_register_device(&snd_rpi_dac_device);
|
|
- bcm_register_device(&snd_pcm1794a_codec_device);
|
|
+ bcm_register_device_dt(&snd_rpi_dac_device);
|
|
+ bcm_register_device_dt(&snd_pcm1794a_codec_device);
|
|
#endif
|
|
|
|
#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE)
|
|
- bcm_register_device(&snd_rpi_iqaudio_dac_device);
|
|
- i2c_register_board_info(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices));
|
|
+ bcm_register_device_dt(&snd_rpi_iqaudio_dac_device);
|
|
+ i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices));
|
|
#endif
|
|
|
|
|
|
@@ -1041,9 +1041,9 @@ static struct platform_device bcm2708_le
|
|
|
|
static void __init bcm2708_init_led(void)
|
|
{
|
|
- bcm2708_leds[0].gpio = disk_led_gpio;
|
|
- bcm2708_leds[0].active_low = disk_led_active_low;
|
|
- platform_device_register(&bcm2708_led_device);
|
|
+ bcm2708_leds[0].gpio = disk_led_gpio;
|
|
+ bcm2708_leds[0].active_low = disk_led_active_low;
|
|
+ bcm_register_device_dt(&bcm2708_led_device);
|
|
}
|
|
#else
|
|
static inline void bcm2708_init_led(void)
|
|
--- a/drivers/dma/bcm2708-dmaengine.c
|
|
+++ b/drivers/dma/bcm2708-dmaengine.c
|
|
@@ -42,7 +42,7 @@
|
|
#include <linux/io.h>
|
|
#include <linux/spinlock.h>
|
|
|
|
-#ifndef CONFIG_OF
|
|
+#ifndef CONFIG_ARCH_BCM2835
|
|
|
|
/* dma manager */
|
|
#include <mach/dma.h>
|
|
@@ -721,7 +721,7 @@ static int bcm2835_dma_control(struct dm
|
|
}
|
|
}
|
|
|
|
-#ifdef CONFIG_OF
|
|
+#ifdef CONFIG_ARCH_BCM2835
|
|
static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id, int irq)
|
|
{
|
|
struct bcm2835_chan *c;
|
|
@@ -784,7 +784,7 @@ static const struct of_device_id bcm2835
|
|
};
|
|
MODULE_DEVICE_TABLE(of, bcm2835_dma_of_match);
|
|
|
|
-#ifdef CONFIG_OF
|
|
+#ifdef CONFIG_ARCH_BCM2835
|
|
static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec,
|
|
struct of_dma *ofdma)
|
|
{
|
|
@@ -817,7 +817,7 @@ static int bcm2835_dma_device_slave_caps
|
|
static int bcm2835_dma_probe(struct platform_device *pdev)
|
|
{
|
|
struct bcm2835_dmadev *od;
|
|
-#ifdef CONFIG_OF
|
|
+#ifdef CONFIG_ARCH_BCM2835
|
|
struct resource *res;
|
|
void __iomem *base;
|
|
uint32_t chans_available;
|
|
@@ -830,10 +830,10 @@ static int bcm2835_dma_probe(struct plat
|
|
if (!pdev->dev.dma_mask)
|
|
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
|
|
|
- /* If CONFIG_OF is selected, device tree is used */
|
|
+ /* If CONFIG_ARCH_BCM2835 is selected, device tree is used */
|
|
/* hence the difference between probing */
|
|
|
|
-#ifndef CONFIG_OF
|
|
+#ifndef CONFIG_ARCH_BCM2835
|
|
|
|
rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
|
|
if (rc)
|
|
@@ -987,7 +987,7 @@ static int bcm2835_dma_remove(struct pla
|
|
return 0;
|
|
}
|
|
|
|
-#ifndef CONFIG_OF
|
|
+#ifndef CONFIG_ARCH_BCM2835
|
|
|
|
|
|
static struct platform_driver bcm2835_dma_driver = {
|
|
--- a/drivers/mmc/host/bcm2835-mmc.c
|
|
+++ b/drivers/mmc/host/bcm2835-mmc.c
|
|
@@ -42,7 +42,7 @@
|
|
#include "sdhci.h"
|
|
|
|
|
|
-#ifndef CONFIG_OF
|
|
+#ifndef CONFIG_ARCH_BCM2835
|
|
#define BCM2835_CLOCK_FREQ 250000000
|
|
#endif
|
|
|
|
@@ -662,7 +662,7 @@ void bcm2835_mmc_send_command(struct bcm
|
|
}
|
|
|
|
timeout = jiffies;
|
|
-#ifdef CONFIG_OF
|
|
+#ifdef CONFIG_ARCH_BCM2835
|
|
if (!cmd->data && cmd->busy_timeout > 9000)
|
|
timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ;
|
|
else
|
|
@@ -962,7 +962,7 @@ static irqreturn_t bcm2835_mmc_irq(int i
|
|
struct bcm2835_host *host = dev_id;
|
|
u32 intmask, mask, unexpected = 0;
|
|
int max_loops = 16;
|
|
-#ifndef CONFIG_OF
|
|
+#ifndef CONFIG_ARCH_BCM2835
|
|
int cardint = 0;
|
|
#endif
|
|
|
|
@@ -993,7 +993,7 @@ static irqreturn_t bcm2835_mmc_irq(int i
|
|
mmc_hostname(host->mmc));
|
|
|
|
if (intmask & SDHCI_INT_CARD_INT) {
|
|
-#ifndef CONFIG_OF
|
|
+#ifndef CONFIG_ARCH_BCM2835
|
|
cardint = 1;
|
|
#else
|
|
bcm2835_mmc_enable_sdio_irq_nolock(host, false);
|
|
@@ -1026,7 +1026,7 @@ out:
|
|
bcm2835_mmc_dumpregs(host);
|
|
}
|
|
|
|
-#ifndef CONFIG_OF
|
|
+#ifndef CONFIG_ARCH_BCM2835
|
|
if (cardint)
|
|
mmc_signal_sdio_irq(host->mmc);
|
|
#endif
|
|
@@ -1034,7 +1034,7 @@ out:
|
|
return result;
|
|
}
|
|
|
|
-#ifdef CONFIG_OF
|
|
+#ifdef CONFIG_ARCH_BCM2835
|
|
static irqreturn_t bcm2835_mmc_thread_irq(int irq, void *dev_id)
|
|
{
|
|
struct bcm2835_host *host = dev_id;
|
|
@@ -1288,7 +1288,7 @@ int bcm2835_mmc_add_host(struct bcm2835_
|
|
|
|
/* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */
|
|
host->timeout_clk = mmc->f_max / 1000;
|
|
-#ifdef CONFIG_OF
|
|
+#ifdef CONFIG_ARCH_BCM2835
|
|
mmc->max_busy_timeout = (1 << 27) / host->timeout_clk;
|
|
#endif
|
|
/* host controller capabilities */
|
|
@@ -1345,7 +1345,7 @@ int bcm2835_mmc_add_host(struct bcm2835_
|
|
init_waitqueue_head(&host->buf_ready_int);
|
|
|
|
bcm2835_mmc_init(host, 0);
|
|
-#ifndef CONFIG_OF
|
|
+#ifndef CONFIG_ARCH_BCM2835
|
|
ret = request_irq(host->irq, bcm2835_mmc_irq, 0 /*IRQF_SHARED*/,
|
|
mmc_hostname(mmc), host);
|
|
#else
|
|
@@ -1374,7 +1374,7 @@ untasklet:
|
|
static int bcm2835_mmc_probe(struct platform_device *pdev)
|
|
{
|
|
struct device *dev = &pdev->dev;
|
|
-#ifdef CONFIG_OF
|
|
+#ifdef CONFIG_ARCH_BCM2835
|
|
struct device_node *node = dev->of_node;
|
|
struct clk *clk;
|
|
#endif
|
|
@@ -1383,7 +1383,7 @@ static int bcm2835_mmc_probe(struct plat
|
|
|
|
int ret;
|
|
struct mmc_host *mmc;
|
|
-#if !defined(CONFIG_OF) && !defined(FORCE_PIO)
|
|
+#if !defined(CONFIG_ARCH_BCM2835) && !defined(FORCE_PIO)
|
|
dma_cap_mask_t mask;
|
|
#endif
|
|
|
|
@@ -1408,7 +1408,7 @@ static int bcm2835_mmc_probe(struct plat
|
|
|
|
host->phys_addr = iomem->start + BCM2835_VCMMU_SHIFT;
|
|
|
|
-#ifndef CONFIG_OF
|
|
+#ifndef CONFIG_ARCH_BCM2835
|
|
#ifndef FORCE_PIO
|
|
dma_cap_zero(mask);
|
|
/* we don't care about the channel, any would work */
|
|
@@ -1458,7 +1458,7 @@ static int bcm2835_mmc_probe(struct plat
|
|
}
|
|
|
|
|
|
-#ifndef CONFIG_OF
|
|
+#ifndef CONFIG_ARCH_BCM2835
|
|
mmc->caps |= MMC_CAP_4_BIT_DATA;
|
|
#else
|
|
mmc_of_parse(mmc);
|
|
--- a/drivers/of/fdt.c
|
|
+++ b/drivers/of/fdt.c
|
|
@@ -1086,8 +1086,12 @@ static struct debugfs_blob_wrapper flat_
|
|
|
|
static int __init of_flat_dt_debugfs_export_fdt(void)
|
|
{
|
|
- struct dentry *d = debugfs_create_dir("device-tree", NULL);
|
|
+ struct dentry *d;
|
|
|
|
+ if (!initial_boot_params)
|
|
+ return -ENOENT;
|
|
+
|
|
+ d = debugfs_create_dir("device-tree", NULL);
|
|
if (!d)
|
|
return -ENOENT;
|
|
|
|
--- a/sound/soc/bcm/bcm2708-i2s.c
|
|
+++ b/sound/soc/bcm/bcm2708-i2s.c
|
|
@@ -493,15 +493,19 @@ static int bcm2708_i2s_hw_params(struct
|
|
divf = dividend & BCM2708_CLK_DIVF_MASK;
|
|
}
|
|
|
|
- /* Set clock divider */
|
|
- regmap_write(dev->clk_regmap, BCM2708_CLK_PCMDIV_REG, BCM2708_CLK_PASSWD
|
|
- | BCM2708_CLK_DIVI(divi)
|
|
- | BCM2708_CLK_DIVF(divf));
|
|
-
|
|
- /* Setup clock, but don't start it yet */
|
|
- regmap_write(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, BCM2708_CLK_PASSWD
|
|
- | BCM2708_CLK_MASH(mash)
|
|
- | BCM2708_CLK_SRC(clk_src));
|
|
+ /* Clock should only be set up here if CPU is clock master */
|
|
+ if (((dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBS_CFS) ||
|
|
+ ((dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBS_CFM)) {
|
|
+ /* Set clock divider */
|
|
+ regmap_write(dev->clk_regmap, BCM2708_CLK_PCMDIV_REG, BCM2708_CLK_PASSWD
|
|
+ | BCM2708_CLK_DIVI(divi)
|
|
+ | BCM2708_CLK_DIVF(divf));
|
|
+
|
|
+ /* Setup clock, but don't start it yet */
|
|
+ regmap_write(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, BCM2708_CLK_PASSWD
|
|
+ | BCM2708_CLK_MASH(mash)
|
|
+ | BCM2708_CLK_SRC(clk_src));
|
|
+ }
|
|
|
|
/* Setup the frame format */
|
|
format = BCM2708_I2S_CHEN;
|
|
@@ -981,12 +985,19 @@ static int bcm2708_i2s_remove(struct pla
|
|
return 0;
|
|
}
|
|
|
|
+static const struct of_device_id bcm2708_i2s_of_match[] = {
|
|
+ { .compatible = "brcm,bcm2708-i2s", },
|
|
+ {},
|
|
+};
|
|
+MODULE_DEVICE_TABLE(of, bcm2708_i2s_of_match);
|
|
+
|
|
static struct platform_driver bcm2708_i2s_driver = {
|
|
.probe = bcm2708_i2s_probe,
|
|
.remove = bcm2708_i2s_remove,
|
|
.driver = {
|
|
.name = "bcm2708-i2s",
|
|
.owner = THIS_MODULE,
|
|
+ .of_match_table = bcm2708_i2s_of_match,
|
|
},
|
|
};
|
|
|
|
--- a/sound/soc/bcm/bcm2835-i2s.c
|
|
+++ b/sound/soc/bcm/bcm2835-i2s.c
|
|
@@ -861,6 +861,7 @@ static const struct of_device_id bcm2835
|
|
{ .compatible = "brcm,bcm2835-i2s", },
|
|
{},
|
|
};
|
|
+MODULE_DEVICE_TABLE(of, bcm2835_i2s_of_match);
|
|
|
|
static struct platform_driver bcm2835_i2s_driver = {
|
|
.probe = bcm2835_i2s_probe,
|