ARM: SoC fixes for 3.7

We've been sitting on this longer than we meant to due to travel and
 other activities, but the number of patches is luckily not that high.
 
 Biggest changes are from a batch of OMAP bugfixes, but there are a
 few for the broader set of SoCs too (bcm2835, pxa, highbank, tegra,
 at91 and i.MX).
 
 The OMAP patches contain some fixes for MUSB/PHY on omap4 which
 ends up being a bit on the large side but needed for legacy (non-DT)
 platforms. Beyond that there are a handful of hwmod/pm changes.
 
 So, fairly noncontroversial stuff all in all, and as usual around this
 time the fixes are well targeted at specific problems.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQIcBAABAgAGBQJQpmQOAAoJEIwa5zzehBx37+YP/jzcKS1pU5Wf73GYIUcCPqO0
 iRwLziexucUkWXnqIIPLedUJ8Dze/8q1tSTnQ7/JSXy9SYtJf651aj5OAo8w/cXO
 d58+y1S+VTsFHbppKfQHbGpYq2n2f4PPvrL24ftp40OmomVl/ktqOB4fDN1/YuAw
 lfTeo0v8MNfyVni5ij21rCNS17IC0Tl4Mfth8zIILWe6qdqajpla7CoO7ppmUM08
 OAPi6NJL/l8vqfqNtGuk2x9cOca0jY1rdib/rfrL1LxrtLT//NP0d6h+wKaSxLWm
 Qvr9nAsnmZNV0pFnYjVxfSMwM6Gf2SBh0QG3lF0akwfe3bEXqfnG5muAtWEhpTlt
 MVx54UgKSWVBgfBH8/SsDkJ3UydxNO5XjHz9YOix1Sj390J2zpP3E24Y0vmYYaNn
 c2seHeH4SckMZ1mddZgy1NT8y7/zaXQ2OSRLyVigJ9wjKmduuOW013BpKUlHFI9E
 Uzh1GLpWe2Cwl3wKWlHRlhgp0NzpWEHhrPW254rOfai8P9xeFMMQH8eqUlSWZbDN
 GAzqUWZ4/F6NxPV1GPrVCZjrA9IYKKtZ5GkPwC1FibC9Kfyb0rp9kr7KM4mzWUY3
 7MxpFatMS4rdbJk5lXCQ1+EIIWF6xdNbURCyMAnoiaowMzdv+LkfBIW+17fDPDgI
 WAu7+QCKTQd+i/bvMsKh
 =aKWl
 -----END PGP SIGNATURE-----

Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull ARM SoC fixes from Olof Johansson:
 "We've been sitting on this longer than we meant to due to travel and
  other activities, but the number of patches is luckily not that high.

  Biggest changes are from a batch of OMAP bugfixes, but there are a few
  for the broader set of SoCs too (bcm2835, pxa, highbank, tegra, at91
  and i.MX).

  The OMAP patches contain some fixes for MUSB/PHY on omap4 which ends
  up being a bit on the large side but needed for legacy (non-DT)
  platforms.  Beyond that there are a handful of hwmod/pm changes.

  So, fairly noncontroversial stuff all in all, and as usual around this
  time the fixes are well targeted at specific problems."

* tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc:
  ARM: imx: ehci: fix host power mask bit
  ARM i.MX: fix error-valued pointer dereference in clk_register_gate2()
  ARM: at91/usbh: fix overcurrent gpio setup
  ARM: at91/AT91SAM9G45: fix crypto peripherals irq issue due to sparse irq support
  ARM: boot: Fix usage of kecho
  ARM: OMAP: ocp2scp: create omap device for ocp2scp
  ARM: OMAP4: add _dev_attr_ to ocp2scp for representing usb_phy
  drivers: bus: ocp2scp: add pdata support
  irqchip: irq-bcm2835: Add terminating entry for of_device_id table
  ARM: highbank: retry wfi on reset request
  ARM: OMAP4: PM: fix regulator name for VDD_MPU
  ARM: OMAP4: hwmod data: do not enable or reset the McPDM during kernel init
  ARM: OMAP2+: hwmod: add flag to prevent hwmod code from touching IP block during init
  ARM: dt: tegra: fix length of pad control and mux registers
  ARM: OMAP: hwmod: wait for sysreset complete after enabling hwmod
  ARM: OMAP2+: clockdomain: Fix OMAP4 ISS clk domain to support only SWSUP
  ARM: pxa/spitz_pm: Fix hang when resuming from STR
  ARM: pxa: hx4700: Fix backlight PWM device number
  ARM: OMAP2+: PM: add missing newline to VC warning message
This commit is contained in:
Linus Torvalds 2012-11-16 10:08:45 -08:00
commit f4bcd79c88
24 changed files with 303 additions and 50 deletions

View File

@ -33,7 +33,7 @@ ifeq ($(CONFIG_XIP_KERNEL),y)
$(obj)/xipImage: vmlinux FORCE
$(call if_changed,objcopy)
$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))'
@$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))'
$(obj)/Image $(obj)/zImage: FORCE
@echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)'
@ -48,14 +48,14 @@ $(obj)/xipImage: FORCE
$(obj)/Image: vmlinux FORCE
$(call if_changed,objcopy)
$(kecho) ' Kernel: $@ is ready'
@$(kecho) ' Kernel: $@ is ready'
$(obj)/compressed/vmlinux: $(obj)/Image FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
$(kecho) ' Kernel: $@ is ready'
@$(kecho) ' Kernel: $@ is ready'
endif
@ -90,7 +90,7 @@ fi
$(obj)/uImage: $(obj)/zImage FORCE
@$(check_for_multiple_loadaddr)
$(call if_changed,uimage)
$(kecho) ' Image $@ is ready'
@$(kecho) ' Image $@ is ready'
$(obj)/bootp/bootp: $(obj)/zImage initrd FORCE
$(Q)$(MAKE) $(build)=$(obj)/bootp $@
@ -98,7 +98,7 @@ $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE
$(obj)/bootpImage: $(obj)/bootp/bootp FORCE
$(call if_changed,objcopy)
$(kecho) ' Kernel: $@ is ready'
@$(kecho) ' Kernel: $@ is ready'
PHONY += initrd FORCE
initrd:

View File

@ -73,8 +73,8 @@
pinmux: pinmux {
compatible = "nvidia,tegra30-pinmux";
reg = <0x70000868 0xd0 /* Pad control registers */
0x70003000 0x3e0>; /* Mux registers */
reg = <0x70000868 0xd4 /* Pad control registers */
0x70003000 0x3e4>; /* Mux registers */
};
serial@70006000 {

View File

@ -68,7 +68,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
/* Enable overcurrent notification */
for (i = 0; i < data->ports; i++) {
if (data->overcurrent_pin[i])
if (gpio_is_valid(data->overcurrent_pin[i]))
at91_set_gpio_input(data->overcurrent_pin[i], 1);
}

View File

@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
/* Enable overcurrent notification */
for (i = 0; i < data->ports; i++) {
if (data->overcurrent_pin[i])
if (gpio_is_valid(data->overcurrent_pin[i]))
at91_set_gpio_input(data->overcurrent_pin[i], 1);
}

View File

@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
/* Enable overcurrent notification */
for (i = 0; i < data->ports; i++) {
if (data->overcurrent_pin[i])
if (gpio_is_valid(data->overcurrent_pin[i]))
at91_set_gpio_input(data->overcurrent_pin[i], 1);
}

View File

@ -78,7 +78,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
/* Enable overcurrent notification */
for (i = 0; i < data->ports; i++) {
if (data->overcurrent_pin[i])
if (gpio_is_valid(data->overcurrent_pin[i]))
at91_set_gpio_input(data->overcurrent_pin[i], 1);
}

View File

@ -1841,8 +1841,8 @@ static struct resource sha_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AT91SAM9G45_ID_AESTDESSHA,
.end = AT91SAM9G45_ID_AESTDESSHA,
.start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
.end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
.flags = IORESOURCE_IRQ,
},
};
@ -1874,8 +1874,8 @@ static struct resource tdes_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AT91SAM9G45_ID_AESTDESSHA,
.end = AT91SAM9G45_ID_AESTDESSHA,
.start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
.end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
.flags = IORESOURCE_IRQ,
},
};
@ -1910,8 +1910,8 @@ static struct resource aes_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AT91SAM9G45_ID_AESTDESSHA,
.end = AT91SAM9G45_ID_AESTDESSHA,
.start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
.end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA,
.flags = IORESOURCE_IRQ,
},
};

View File

@ -28,6 +28,7 @@ void highbank_restart(char mode, const char *cmd)
hignbank_set_pwr_soft_reset();
scu_power_mode(scu_base_addr, SCU_PM_POWEROFF);
cpu_do_idle();
while (1)
cpu_do_idle();
}

View File

@ -112,7 +112,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
clk = clk_register(dev, &gate->hw);
if (IS_ERR(clk))
kfree(clk);
kfree(gate);
return clk;
}

View File

@ -30,7 +30,7 @@
#define MX25_H1_SIC_SHIFT 21
#define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT)
#define MX25_H1_PP_BIT (1 << 18)
#define MX25_H1_PM_BIT (1 << 8)
#define MX25_H1_PM_BIT (1 << 16)
#define MX25_H1_IPPUE_UP_BIT (1 << 7)
#define MX25_H1_IPPUE_DOWN_BIT (1 << 6)
#define MX25_H1_TLL_BIT (1 << 5)

View File

@ -30,7 +30,7 @@
#define MX35_H1_SIC_SHIFT 21
#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT)
#define MX35_H1_PP_BIT (1 << 18)
#define MX35_H1_PM_BIT (1 << 8)
#define MX35_H1_PM_BIT (1 << 16)
#define MX35_H1_IPPUE_UP_BIT (1 << 7)
#define MX35_H1_IPPUE_DOWN_BIT (1 << 6)
#define MX35_H1_TLL_BIT (1 << 5)

View File

@ -359,7 +359,7 @@ static struct clockdomain iss_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS,
.wkdep_srcs = iss_wkup_sleep_deps,
.sleepdep_srcs = iss_wkup_sleep_deps,
.flags = CLKDM_CAN_HWSUP_SWSUP,
.flags = CLKDM_CAN_SWSUP,
};
static struct clockdomain l3_dss_44xx_clkdm = {

View File

@ -19,6 +19,7 @@
#include <linux/of.h>
#include <linux/pinctrl/machine.h>
#include <linux/platform_data/omap4-keypad.h>
#include <linux/platform_data/omap_ocp2scp.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
@ -613,6 +614,83 @@ static void omap_init_vout(void)
static inline void omap_init_vout(void) {}
#endif
#if defined(CONFIG_OMAP_OCP2SCP) || defined(CONFIG_OMAP_OCP2SCP_MODULE)
static int count_ocp2scp_devices(struct omap_ocp2scp_dev *ocp2scp_dev)
{
int cnt = 0;
while (ocp2scp_dev->drv_name != NULL) {
cnt++;
ocp2scp_dev++;
}
return cnt;
}
static void omap_init_ocp2scp(void)
{
struct omap_hwmod *oh;
struct platform_device *pdev;
int bus_id = -1, dev_cnt = 0, i;
struct omap_ocp2scp_dev *ocp2scp_dev;
const char *oh_name, *name;
struct omap_ocp2scp_platform_data *pdata;
if (!cpu_is_omap44xx())
return;
oh_name = "ocp2scp_usb_phy";
name = "omap-ocp2scp";
oh = omap_hwmod_lookup(oh_name);
if (!oh) {
pr_err("%s: could not find omap_hwmod for %s\n", __func__,
oh_name);
return;
}
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
pr_err("%s: No memory for ocp2scp pdata\n", __func__);
return;
}
ocp2scp_dev = oh->dev_attr;
dev_cnt = count_ocp2scp_devices(ocp2scp_dev);
if (!dev_cnt) {
pr_err("%s: No devices connected to ocp2scp\n", __func__);
kfree(pdata);
return;
}
pdata->devices = kzalloc(sizeof(struct omap_ocp2scp_dev *)
* dev_cnt, GFP_KERNEL);
if (!pdata->devices) {
pr_err("%s: No memory for ocp2scp pdata devices\n", __func__);
kfree(pdata);
return;
}
for (i = 0; i < dev_cnt; i++, ocp2scp_dev++)
pdata->devices[i] = ocp2scp_dev;
pdata->dev_cnt = dev_cnt;
pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL,
0, false);
if (IS_ERR(pdev)) {
pr_err("Could not build omap_device for %s %s\n",
name, oh_name);
kfree(pdata->devices);
kfree(pdata);
return;
}
}
#else
static inline void omap_init_ocp2scp(void) { }
#endif
/*-------------------------------------------------------------------------*/
static int __init omap2_init_devices(void)
@ -640,6 +718,7 @@ static int __init omap2_init_devices(void)
omap_init_sham();
omap_init_aes();
omap_init_vout();
omap_init_ocp2scp();
return 0;
}

View File

@ -421,6 +421,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)
return 0;
}
/**
* _wait_softreset_complete - wait for an OCP softreset to complete
* @oh: struct omap_hwmod * to wait on
*
* Wait until the IP block represented by @oh reports that its OCP
* softreset is complete. This can be triggered by software (see
* _ocp_softreset()) or by hardware upon returning from off-mode (one
* example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT
* microseconds. Returns the number of microseconds waited.
*/
static int _wait_softreset_complete(struct omap_hwmod *oh)
{
struct omap_hwmod_class_sysconfig *sysc;
u32 softrst_mask;
int c = 0;
sysc = oh->class->sysc;
if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs)
& SYSS_RESETDONE_MASK),
MAX_MODULE_SOFTRESET_WAIT, c);
else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
softrst_mask = (0x1 << sysc->sysc_fields->srst_shift);
omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs)
& softrst_mask),
MAX_MODULE_SOFTRESET_WAIT, c);
}
return c;
}
/**
* _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v
* @oh: struct omap_hwmod *
@ -1282,6 +1314,18 @@ static void _enable_sysc(struct omap_hwmod *oh)
if (!oh->class->sysc)
return;
/*
* Wait until reset has completed, this is needed as the IP
* block is reset automatically by hardware in some cases
* (off-mode for example), and the drivers require the
* IP to be ready when they access it
*/
if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
_enable_optional_clocks(oh);
_wait_softreset_complete(oh);
if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
_disable_optional_clocks(oh);
v = oh->_sysc_cache;
sf = oh->class->sysc->sysc_flags;
@ -1804,7 +1848,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh)
*/
static int _ocp_softreset(struct omap_hwmod *oh)
{
u32 v, softrst_mask;
u32 v;
int c = 0;
int ret = 0;
@ -1834,19 +1878,7 @@ static int _ocp_softreset(struct omap_hwmod *oh)
if (oh->class->sysc->srst_udelay)
udelay(oh->class->sysc->srst_udelay);
if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
omap_test_timeout((omap_hwmod_read(oh,
oh->class->sysc->syss_offs)
& SYSS_RESETDONE_MASK),
MAX_MODULE_SOFTRESET_WAIT, c);
else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) {
softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
omap_test_timeout(!(omap_hwmod_read(oh,
oh->class->sysc->sysc_offs)
& softrst_mask),
MAX_MODULE_SOFTRESET_WAIT, c);
}
c = _wait_softreset_complete(oh);
if (c == MAX_MODULE_SOFTRESET_WAIT)
pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
oh->name, MAX_MODULE_SOFTRESET_WAIT);
@ -2352,6 +2384,9 @@ static int __init _setup_reset(struct omap_hwmod *oh)
if (oh->_state != _HWMOD_STATE_INITIALIZED)
return -EINVAL;
if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK)
return -EPERM;
if (oh->rst_lines_cnt == 0) {
r = _enable(oh);
if (r) {

View File

@ -21,6 +21,7 @@
#include <linux/io.h>
#include <linux/platform_data/gpio-omap.h>
#include <linux/power/smartreflex.h>
#include <linux/platform_data/omap_ocp2scp.h>
#include <plat/omap_hwmod.h>
#include <plat/i2c.h>
@ -2125,6 +2126,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = {
.name = "mcpdm",
.class = &omap44xx_mcpdm_hwmod_class,
.clkdm_name = "abe_clkdm",
/*
* It's suspected that the McPDM requires an off-chip main
* functional clock, controlled via I2C. This IP block is
* currently reset very early during boot, before I2C is
* available, so it doesn't seem that we have any choice in
* the kernel other than to avoid resetting it.
*/
.flags = HWMOD_EXT_OPT_MAIN_CLK,
.mpu_irqs = omap44xx_mcpdm_irqs,
.sdma_reqs = omap44xx_mcpdm_sdma_reqs,
.main_clk = "mcpdm_fck",
@ -2681,6 +2690,32 @@ static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = {
.sysc = &omap44xx_ocp2scp_sysc,
};
/* ocp2scp dev_attr */
static struct resource omap44xx_usb_phy_and_pll_addrs[] = {
{
.name = "usb_phy",
.start = 0x4a0ad080,
.end = 0x4a0ae000,
.flags = IORESOURCE_MEM,
},
{
/* XXX: Remove this once control module driver is in place */
.name = "ctrl_dev",
.start = 0x4a002300,
.end = 0x4a002303,
.flags = IORESOURCE_MEM,
},
{ }
};
static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = {
{
.drv_name = "omap-usb2",
.res = omap44xx_usb_phy_and_pll_addrs,
},
{ }
};
/* ocp2scp_usb_phy */
static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
.name = "ocp2scp_usb_phy",
@ -2694,6 +2729,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
.modulemode = MODULEMODE_HWCTRL,
},
},
.dev_attr = ocp2scp_dev_attr,
};
/*

View File

@ -366,7 +366,7 @@ static struct regulator_init_data omap4_clk32kg_idata = {
};
static struct regulator_consumer_supply omap4_vdd1_supply[] = {
REGULATOR_SUPPLY("vcc", "mpu.0"),
REGULATOR_SUPPLY("vcc", "cpu0"),
};
static struct regulator_consumer_supply omap4_vdd2_supply[] = {

View File

@ -264,7 +264,7 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)
if (initialized) {
if (voltdm->pmic->i2c_high_speed != i2c_high_speed)
pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).",
pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).\n",
__func__, voltdm->name, i2c_high_speed);
return;
}

View File

@ -28,6 +28,7 @@
#include <linux/mfd/asic3.h>
#include <linux/mtd/physmap.h>
#include <linux/pda_power.h>
#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/gpio-regulator.h>
@ -556,7 +557,7 @@ static struct platform_device hx4700_lcd = {
*/
static struct platform_pwm_backlight_data backlight_data = {
.pwm_id = 1,
.pwm_id = -1, /* Superseded by pwm_lookup */
.max_brightness = 200,
.dft_brightness = 100,
.pwm_period_ns = 30923,
@ -571,6 +572,10 @@ static struct platform_device backlight = {
},
};
static struct pwm_lookup hx4700_pwm_lookup[] = {
PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL),
};
/*
* USB "Transceiver"
*/
@ -872,6 +877,7 @@ static void __init hx4700_init(void)
pxa_set_stuart_info(NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup));
pxa_set_ficp_info(&ficp_info);
pxa27x_set_i2c_power_info(NULL);

View File

@ -86,10 +86,7 @@ static void spitz_discharge1(int on)
gpio_set_value(SPITZ_GPIO_LED_GREEN, on);
}
static unsigned long gpio18_config[] = {
GPIO18_RDY,
GPIO18_GPIO,
};
static unsigned long gpio18_config = GPIO18_GPIO;
static void spitz_presuspend(void)
{
@ -112,7 +109,7 @@ static void spitz_presuspend(void)
PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0);
pxa2xx_mfp_config(&gpio18_config[0], 1);
pxa2xx_mfp_config(&gpio18_config, 1);
gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown");
gpio_free(18);
@ -131,7 +128,6 @@ static void spitz_presuspend(void)
static void spitz_postsuspend(void)
{
pxa2xx_mfp_config(&gpio18_config[1], 1);
}
static int spitz_should_wakeup(unsigned int resume_on_alarm)

View File

@ -443,6 +443,11 @@ struct omap_hwmod_omap4_prcm {
* in order to complete the reset. Optional clocks will be disabled
* again after the reset.
* HWMOD_16BIT_REG: Module has 16bit registers
* HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for
* this IP block comes from an off-chip source and is not always
* enabled. This prevents the hwmod code from being able to
* enable and reset the IP block early. XXX Eventually it should
* be possible to query the clock framework for this information.
*/
#define HWMOD_SWSUP_SIDLE (1 << 0)
#define HWMOD_SWSUP_MSTANDBY (1 << 1)
@ -453,6 +458,7 @@ struct omap_hwmod_omap4_prcm {
#define HWMOD_NO_IDLEST (1 << 6)
#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7)
#define HWMOD_16BIT_REG (1 << 8)
#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9)
/*
* omap_hwmod._int_flags definitions

View File

@ -5,6 +5,6 @@
#
include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types
$(kecho) ' Generating $@'
@$(kecho) ' Generating $@'
@mkdir -p $(dir $@)
$(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; }

View File

@ -22,6 +22,26 @@
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_data/omap_ocp2scp.h>
/**
* _count_resources - count for the number of resources
* @res: struct resource *
*
* Count and return the number of resources populated for the device that is
* connected to ocp2scp.
*/
static unsigned _count_resources(struct resource *res)
{
int cnt = 0;
while (res->start != res->end) {
cnt++;
res++;
}
return cnt;
}
static int ocp2scp_remove_devices(struct device *dev, void *c)
{
@ -34,20 +54,62 @@ static int ocp2scp_remove_devices(struct device *dev, void *c)
static int __devinit omap_ocp2scp_probe(struct platform_device *pdev)
{
int ret;
struct device_node *np = pdev->dev.of_node;
int ret;
unsigned res_cnt, i;
struct device_node *np = pdev->dev.of_node;
struct platform_device *pdev_child;
struct omap_ocp2scp_platform_data *pdata = pdev->dev.platform_data;
struct omap_ocp2scp_dev *dev;
if (np) {
ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
if (ret) {
dev_err(&pdev->dev, "failed to add resources for ocp2scp child\n");
dev_err(&pdev->dev,
"failed to add resources for ocp2scp child\n");
goto err0;
}
} else if (pdata) {
for (i = 0, dev = *pdata->devices; i < pdata->dev_cnt; i++,
dev++) {
res_cnt = _count_resources(dev->res);
pdev_child = platform_device_alloc(dev->drv_name,
PLATFORM_DEVID_AUTO);
if (!pdev_child) {
dev_err(&pdev->dev,
"failed to allocate mem for ocp2scp child\n");
goto err0;
}
ret = platform_device_add_resources(pdev_child,
dev->res, res_cnt);
if (ret) {
dev_err(&pdev->dev,
"failed to add resources for ocp2scp child\n");
goto err1;
}
pdev_child->dev.parent = &pdev->dev;
ret = platform_device_add(pdev_child);
if (ret) {
dev_err(&pdev->dev,
"failed to register ocp2scp child device\n");
goto err1;
}
}
} else {
dev_err(&pdev->dev, "OCP2SCP initialized without plat data\n");
return -EINVAL;
}
pm_runtime_enable(&pdev->dev);
return 0;
err1:
platform_device_put(pdev_child);
err0:
device_for_each_child(&pdev->dev, NULL, ocp2scp_remove_devices);

View File

@ -168,7 +168,8 @@ static int __init armctrl_of_init(struct device_node *node,
}
static struct of_device_id irq_of_match[] __initconst = {
{ .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init }
{ .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init },
{ }
};
void __init bcm2835_init_irq(void)

View File

@ -0,0 +1,31 @@
/*
* omap_ocp2scp.h -- ocp2scp header file
*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Author: Kishon Vijay Abraham I <kishon@ti.com>
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __DRIVERS_OMAP_OCP2SCP_H
#define __DRIVERS_OMAP_OCP2SCP_H
struct omap_ocp2scp_dev {
const char *drv_name;
struct resource *res;
};
struct omap_ocp2scp_platform_data {
int dev_cnt;
struct omap_ocp2scp_dev **devices;
};
#endif /* __DRIVERS_OMAP_OCP2SCP_H */