* Re: [PATCH 02/12] ASoC: dapm: Implement stereo mixer control support
From: Chen-Yu Tsai @ 2016-10-27 1:20 UTC (permalink / raw)
To: Mark Brown
Cc: Chen-Yu Tsai, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
Rob Herring, Mark Rutland, Russell King, Maxime Ripard,
Linux-ALSA, linux-arm-kernel, linux-kernel, devicetree,
linux-sunxi
In-Reply-To: <20161026165753.GC25322-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
On Thu, Oct 27, 2016 at 12:57 AM, Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Mon, Oct 03, 2016 at 07:07:54PM +0800, Chen-Yu Tsai wrote:
>
>> While DAPM is mono or single channel, its controls can be shared between
>> widgets, such as sharing one stereo mixer control between the left and
>> right channel widgets.
>
>> This patch introduces support for such shared mixer controls.
>
> Based on this changelog I'm really not sure what the intended semantic
> of this change is which makes it difficult to review. What are you
> expecting these controls to look like and how are you expecting them to
> work?
>
>> -static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i)
>> +static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i,
>> + int nth_path)
>
> It looks like the goal is to attach more than one path to a single
> control somehow?
Correct. I'll try to expand the commit log and add an example diagram.
ChenYu
^ permalink raw reply
* Re: [PATCH 5/5] ARM: dts: Add LEGO MINDSTORTMS EV3 dts
From: David Lechner @ 2016-10-27 1:30 UTC (permalink / raw)
To: Sekhar Nori, Kevin Hilman
Cc: Rob Herring, Mark Rutland, Russell King,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <b0022fad-a96e-86d4-71ba-2b803e5421fe-l0cyMroinI0@public.gmane.org>
On 10/24/2016 06:58 AM, Sekhar Nori wrote:
> On Saturday 22 October 2016 12:06 AM, David Lechner wrote:
>> This adds a device tree definition file for LEGO MINDSTORMS EV3.
>
> Thanks for the patch!
>
>>
>> What is working:
>>
>> * Pin muxing
>> * MicroSD card reader
>> * UART on input port 1
>>
>> What is partially working:
>>
>> * Buttons - working after GPIO fix
>> * LEDs - working after GPIO fix
>> * Poweroff/reset - working after GPIO fix
>
> Is the GPIO fix something that will go in v4.9-rc cycle ?
>
FYI, the fix is in linux-gpio/fixes now.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v4] drm/mediatek: fixed the calc method of data rate per lane
From: Jitao Shi @ 2016-10-27 2:21 UTC (permalink / raw)
To: Philipp Zabel, ck.hu, Matthias Brugger
Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Jitao Shi, Ajay Kumar, Inki Dae, Rahul Sharma, Sean Paul,
Vincent Palatin, Andy Yan, Russell King, devicetree, linux-kernel,
dri-devel, linux-arm-kernel, linux-mediatek, srv_heupstream,
Sascha Hauer, yingjoe.chen
Tune dsi frame rate by pixel clock, dsi add some extra signal (i.e.
Tlpx, Ths-prepare, Ths-zero, Ths-trail,Ths-exit) when enter and exit LP
mode, those signals will cause h-time larger than normal and reduce FPS.
So need to multiply a coefficient to offset the extra signal's effect.
coefficient = ((htotal*bpp/lane_number)+Tlpx+Ths_prep+Ths_zero+
Ths_trail+Ths_exit)/(htotal*bpp/lane_number)
Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
---
Chnage since v3:
- wrapp the commit msg.
- fix alignment of some lines.
Change since v2:
- move phy timing back to dsi_phy_timconfig.
Change since v1:
- phy_timing2 and phy_timing3 refer clock cycle time.
- define values of LPX HS_PRPR HS_ZERO HS_TRAIL TA_GO TA_SURE TA_GET DA_HS_EXIT.
---
drivers/gpu/drm/mediatek/mtk_dsi.c | 71 +++++++++++++++++++++++++-----------
1 file changed, 49 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 28b2044..5defe58 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -85,16 +85,16 @@
#define LD0_WAKEUP_EN BIT(2)
#define DSI_PHY_TIMECON0 0x110
-#define LPX (0xff << 0)
-#define HS_PRPR (0xff << 8)
-#define HS_ZERO (0xff << 16)
-#define HS_TRAIL (0xff << 24)
+#define LPX (5 << 0)
+#define HS_PRPR (6 << 8)
+#define HS_ZERO (10 << 16)
+#define HS_TRAIL (8 << 24)
#define DSI_PHY_TIMECON1 0x114
-#define TA_GO (0xff << 0)
-#define TA_SURE (0xff << 8)
-#define TA_GET (0xff << 16)
-#define DA_HS_EXIT (0xff << 24)
+#define TA_GO (20 << 0)
+#define TA_SURE (7 << 8)
+#define TA_GET (25 << 16)
+#define DA_HS_EXIT (7 << 24)
#define DSI_PHY_TIMECON2 0x118
#define CONT_DET (0xff << 0)
@@ -161,20 +161,17 @@ static void mtk_dsi_mask(struct mtk_dsi *dsi, u32 offset, u32 mask, u32 data)
static void dsi_phy_timconfig(struct mtk_dsi *dsi)
{
u32 timcon0, timcon1, timcon2, timcon3;
- unsigned int ui, cycle_time;
- unsigned int lpx;
+ u32 ui, cycle_time;
ui = 1000 / dsi->data_rate + 0x01;
cycle_time = 8000 / dsi->data_rate + 0x01;
- lpx = 5;
- timcon0 = (8 << 24) | (0xa << 16) | (0x6 << 8) | lpx;
- timcon1 = (7 << 24) | (5 * lpx << 16) | ((3 * lpx) / 2) << 8 |
- (4 * lpx);
+ timcon0 = LPX | HS_PRPR | HS_ZERO | HS_TRAIL;
+ timcon1 = 4 * LPX | (3 * LPX / 2) << 8 | 5 * LPX << 16 | DA_HS_EXIT;
timcon2 = ((NS_TO_CYCLE(0x64, cycle_time) + 0xa) << 24) |
(NS_TO_CYCLE(0x150, cycle_time) << 16);
- timcon3 = (2 * lpx) << 16 | NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8 |
- NS_TO_CYCLE(0x40, cycle_time);
+ timcon3 = NS_TO_CYCLE(0x40, cycle_time) | (2 * LPX) << 16 |
+ NS_TO_CYCLE(80 + 52 * ui, cycle_time) << 8;
writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
@@ -202,19 +199,49 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
{
struct device *dev = dsi->dev;
int ret;
+ u64 bit_clock, total_bits;
+ u32 htotal, htotal_bits, bit_per_pixel, overhead_cycles, overhead_bits;
if (++dsi->refcount != 1)
return 0;
+ switch (dsi->format) {
+ case MIPI_DSI_FMT_RGB565:
+ bit_per_pixel = 16;
+ break;
+ case MIPI_DSI_FMT_RGB666_PACKED:
+ bit_per_pixel = 18;
+ break;
+ case MIPI_DSI_FMT_RGB666:
+ case MIPI_DSI_FMT_RGB888:
+ default:
+ bit_per_pixel = 24;
+ break;
+ }
/**
- * data_rate = (pixel_clock / 1000) * pixel_dipth * mipi_ratio;
- * pixel_clock unit is Khz, data_rata unit is MHz, so need divide 1000.
- * mipi_ratio is mipi clk coefficient for balance the pixel clk in mipi.
- * we set mipi_ratio is 1.05.
+ * data_rate = (pixel_clock) * bit_per_pixel * mipi_ratio / lane_num;
+ * vm.pixelclock is Khz, data_rata unit is Hz, so need to multiply 1000
+ * mipi_ratio is (htotal * byte_per_pixel / lane_num + Tlpx + Ths_prep
+ * + Thstrail + Ths_exit + Ths_zero) /
+ * (htotal * byte_per_pixel /lane_number)
*/
- dsi->data_rate = dsi->vm.pixelclock * 3 * 21 / (1 * 1000 * 10);
+ bit_clock = dsi->vm.pixelclock * 1000 * bit_per_pixel;
+ htotal = dsi->vm.hactive + dsi->vm.hback_porch + dsi->vm.hfront_porch +
+ dsi->vm.hsync_len;
+ htotal_bits = htotal * bit_per_pixel;
+
+ /**
+ * overhead = lpx + hs_prepare + hs_zero + hs_trail + hs_exit
+ */
+ overhead_cycles = LPX + (HS_PRPR >> 8) + (HS_ZERO >> 16) +
+ (HS_TRAIL >> 24) + (DA_HS_EXIT >> 24);
+ overhead_bits = overhead_cycles * dsi->lanes * 8;
+ total_bits = htotal_bits + overhead_bits;
+
+ dsi->data_rate = DIV_ROUND_UP_ULL(bit_clock * total_bits,
+ htotal_bits * dsi->lanes);
- ret = clk_set_rate(dsi->hs_clk, dsi->data_rate * 1000000);
+ ret = clk_set_rate(dsi->hs_clk, dsi->data_rate);
if (ret < 0) {
dev_err(dev, "Failed to set data rate: %d\n", ret);
goto err_refcount;
--
1.7.9.5
^ permalink raw reply related
* RE: [PATCH v5] drm/fsl-dcu: Implement gamma_lut atomic crtc properties
From: Meng Yi @ 2016-10-27 2:49 UTC (permalink / raw)
To: Stefan Agner, robh+dt@kernel.org, mark.rutland@arm.com,
devicetree@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
In-Reply-To: <f539ebe1fe2086d67e74e5b7e8ce2e6a@agner.ch>
> Subject: Re: [PATCH v5] drm/fsl-dcu: Implement gamma_lut atomic crtc
> properties
>
> On 2016-09-28 01:24, Meng Yi wrote:
> > Gamma correction is optional and can be used to adjust the color
> > output values to match the gamut of a particular TFT LCD panel
> >
> > Split the DCU regs into "regs", "palette", "gamma" and "cursor".
> > Create a second regmap for gamma memory space using little endian.
> > The registers after the first address space are not accessed yet,
> > hence new device trees would even work with old kernels. Just new
> > kernel need the new format so we can access the separate gamma reg
> > space.
> >
> > Suggested-by: Stefan Agner <stefan@agner.ch>
> > Signed-off-by: Meng Yi <meng.yi@nxp.com>
> > ---
> > Changes since V1:
> > -created a second regmap for gamma
> > -updated the DCU DT binding
> > -removed Kconfig for gamma and enable gamma when valid data filled.
> > -extended and simplified comment lines.
> > ---
> > .../devicetree/bindings/display/fsl,dcu.txt | 12 +++++++-
> > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c | 33
> ++++++++++++++++++++
> > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 35
> +++++++++++++++++++++-
> > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h | 7 +++++
> > 4 files changed, 85 insertions(+), 2 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/display/fsl,dcu.txt
> > b/Documentation/devicetree/bindings/display/fsl,dcu.txt
> > index 63ec2a6..8140b5d 100644
> > --- a/Documentation/devicetree/bindings/display/fsl,dcu.txt
> > +++ b/Documentation/devicetree/bindings/display/fsl,dcu.txt
> > @@ -6,6 +6,12 @@ Required properties:
> > * "fsl,vf610-dcu".
> >
> > - reg: Address and length of the register set for dcu.
> > + Must contain four address/length tuples:
> > + 1. Register address space
> > + 2. Palette/Tile address space
> > + 3. Gamma address space
> > + 4. Cursor address space
> > +- reg-names: Should be "regs", "palette", "gamma" and
> "cursor"
>
> Looks good to me, device tree folks?
>
> --
> Stefan
>
Tested-by: Meng Yi <meng.yi@nxp.com>
On LS1021A-TWR board.
Meng
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH v2 3/4] usb: musb: da8xx: Add DT support for the DA8xx driver
From: David Lechner @ 2016-10-27 3:26 UTC (permalink / raw)
To: Alexandre Bailon, khilman-rdvid1DuHRBWk0Htik3J/w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, b-liu-l0cyMroinI0
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Petr Kulhavy,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1477494237-22831-4-git-send-email-abailon-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
On 10/26/2016 10:03 AM, Alexandre Bailon wrote:
> From: Petr Kulhavy <petr-Qh/3xLP0EvwAvxtiuMwx3w@public.gmane.org>
>
> This adds DT support for TI DA8xx/OMAP-L1x/AM17xx/AM18xx MUSB driver
>
> Signed-off-by: Petr Kulhavy <petr-Qh/3xLP0EvwAvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Alexandre Bailon <abailon-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
> drivers/usb/musb/da8xx.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 47 insertions(+)
>
> diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
> index 210b7e4..bfa571d 100644
> --- a/drivers/usb/musb/da8xx.c
> +++ b/drivers/usb/musb/da8xx.c
> @@ -6,6 +6,9 @@
> * Based on the DaVinci "glue layer" code.
> * Copyright (C) 2005-2006 by Texas Instruments
> *
> + * DT support
> + * Copyright (c) 2016 Petr Kulhavy <petr-Qh/3xLP0EvwAvxtiuMwx3w@public.gmane.org>
> + *
> * This file is part of the Inventra Controller Driver for Linux.
> *
> * The Inventra Controller Driver for Linux is free software; you
> @@ -433,6 +436,21 @@ static int da8xx_musb_exit(struct musb *musb)
> return 0;
> }
>
> +static inline u8 get_vbus_power(struct device *dev)
> +{
> + struct regulator *vbus_supply;
> + int current_uA;
> +
> + vbus_supply = regulator_get_optional(dev, "vbus");
> + if (IS_ERR(vbus_supply))
> + return 255;
> + current_uA = regulator_get_current_limit(vbus_supply);
> + regulator_put(vbus_supply);
> + if (current_uA <= 0 || current_uA > 510000)
> + return 255;
> + return current_uA / 1000 / 2;
> +}
> +
> static const struct musb_platform_ops da8xx_ops = {
> .quirks = MUSB_DMA_CPPI | MUSB_INDEXED_EP,
> .init = da8xx_musb_init,
> @@ -458,6 +476,12 @@ static const struct platform_device_info da8xx_dev_info = {
> .dma_mask = DMA_BIT_MASK(32),
> };
>
> +static const struct musb_hdrc_config da8xx_config = {
> + .ram_bits = 10,
> + .num_eps = 5,
> + .multipoint = 1,
> +};
> +
> static int da8xx_probe(struct platform_device *pdev)
> {
> struct resource musb_resources[2];
> @@ -465,7 +489,9 @@ static int da8xx_probe(struct platform_device *pdev)
> struct da8xx_glue *glue;
> struct platform_device_info pinfo;
> struct clk *clk;
> + struct device_node *np = pdev->dev.of_node;
> int ret;
> + struct resource *res;
res is not used anywhere
>
> glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
> if (!glue)
> @@ -486,6 +512,18 @@ static int da8xx_probe(struct platform_device *pdev)
> glue->dev = &pdev->dev;
> glue->clk = clk;
>
> + if (IS_ENABLED(CONFIG_OF) && np) {
> + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
> + if (!pdata) {
> + /* FIXME */
Why FIXME? I don't see anything that needs to be fixed here.
> + return -ENOMEM;
> + }
> +
> + pdata->config = &da8xx_config;
> + pdata->mode = musb_get_mode(&pdev->dev);
> + pdata->power = get_vbus_power(&pdev->dev);
> + }
> +
> pdata->platform_ops = &da8xx_ops;
>
> glue->usb_phy = usb_phy_generic_register();
> @@ -536,11 +574,20 @@ static int da8xx_remove(struct platform_device *pdev)
> return 0;
> }
>
Shouldn't you have #ifdef CONFIG_OF here since you are using
of_match_ptr() below?
> +static const struct of_device_id da8xx_id_table[] = {
> + {
> + .compatible = "ti,da830-musb",
> + },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, da8xx_id_table);
#endif
> +
> static struct platform_driver da8xx_driver = {
> .probe = da8xx_probe,
> .remove = da8xx_remove,
> .driver = {
> .name = "musb-da8xx",
> + .of_match_table = of_match_ptr(da8xx_id_table),
> },
> };
>
>
Tested working on LEGO MINDSTORMS EV3 using dr_mode = "peripheral" and
no vbus-supply.
Tested-By: David Lechner <david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 2/4] usb: musb: core: added helper function for parsing DT
From: David Lechner @ 2016-10-27 3:27 UTC (permalink / raw)
To: Alexandre Bailon, khilman-rdvid1DuHRBWk0Htik3J/w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, b-liu-l0cyMroinI0
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Petr Kulhavy,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <1477494237-22831-3-git-send-email-abailon-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
On 10/26/2016 10:03 AM, Alexandre Bailon wrote:
> From: Petr Kulhavy <petr-Qh/3xLP0EvwAvxtiuMwx3w@public.gmane.org>
>
> This adds the function musb_get_mode() to get the DT property "dr_mode"
>
> Signed-off-by: Petr Kulhavy <petr-Qh/3xLP0EvwAvxtiuMwx3w@public.gmane.org>
> Acked-by: Sergei Shtylyov <sshtylyov-hkdhdckH98+B+jHODAdFcQ@public.gmane.org>
> Signed-off-by: Alexandre Bailon <abailon-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
> drivers/usb/musb/musb_core.c | 19 +++++++++++++++++++
> drivers/usb/musb/musb_core.h | 5 +++++
> 2 files changed, 24 insertions(+)
>
> diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
> index 27dadc0..bba07e7 100644
> --- a/drivers/usb/musb/musb_core.c
> +++ b/drivers/usb/musb/musb_core.c
> @@ -100,6 +100,7 @@
> #include <linux/io.h>
> #include <linux/dma-mapping.h>
> #include <linux/usb.h>
> +#include <linux/usb/of.h>
>
> #include "musb_core.h"
> #include "musb_trace.h"
> @@ -130,6 +131,24 @@ static inline struct musb *dev_to_musb(struct device *dev)
> return dev_get_drvdata(dev);
> }
>
> +enum musb_mode musb_get_mode(struct device *dev)
> +{
> + enum usb_dr_mode mode;
> +
> + mode = usb_get_dr_mode(dev);
> + switch (mode) {
> + case USB_DR_MODE_HOST:
> + return MUSB_HOST;
> + case USB_DR_MODE_PERIPHERAL:
> + return MUSB_PERIPHERAL;
> + case USB_DR_MODE_OTG:
> + case USB_DR_MODE_UNKNOWN:
> + default:
> + return MUSB_OTG;
> + }
> +}
> +EXPORT_SYMBOL_GPL(musb_get_mode);
> +
> /*-------------------------------------------------------------------------*/
>
> #ifndef CONFIG_BLACKFIN
> diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
> index 2cb88a49..a406468 100644
> --- a/drivers/usb/musb/musb_core.h
> +++ b/drivers/usb/musb/musb_core.h
> @@ -617,4 +617,9 @@ static inline void musb_platform_post_root_reset_end(struct musb *musb)
> musb->ops->post_root_reset_end(musb);
> }
>
> +/* gets the "dr_mode" property from DT and converts it into musb_mode
> + * if the property is not found or not recognized returns MUSB_OTG
> + */
> +extern enum musb_mode musb_get_mode(struct device *dev);
> +
> #endif /* __MUSB_CORE_H__ */
>
Tested working on LEGO MINDSTORMS EV3 using dr_mode = "peripheral" and
no vbus-supply.
Tested-By: David Lechner <david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 1/2] ARM: dts: uniphier: add CPU clocks and OPP table for Pro5 SoC
From: Viresh Kumar @ 2016-10-27 3:27 UTC (permalink / raw)
To: Masahiro Yamada
Cc: linux-arm-kernel, linux-pm, devicetree, linux-kernel, Rob Herring,
Mark Rutland, Russell King
In-Reply-To: <1477499859-12415-1-git-send-email-yamada.masahiro@socionext.com>
On 27-10-16, 01:37, Masahiro Yamada wrote:
> Add a CPU clock to every CPU node and a CPU OPP table to use the
> generic cpufreq driver.
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
> ---
>
> arch/arm/boot/dts/uniphier-pro5.dtsi | 74 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 74 insertions(+)
For both patches.
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
--
viresh
^ permalink raw reply
* Re: [PATCH 5/5] gpio: davinci: Add a separate compatible for k2g
From: Keerthy @ 2016-10-27 3:28 UTC (permalink / raw)
To: Rob Herring
Cc: linus.walleij, gnurou, lokeshvutla, linux-gpio, devicetree,
linux-omap, rogerq, grygorii.strashko
In-Reply-To: <20161026210851.jt2xoo2ap6zijowg@rob-hp-laptop>
On Thursday 27 October 2016 02:38 AM, Rob Herring wrote:
> On Wed, Oct 19, 2016 at 11:03:59AM +0530, Keerthy wrote:
>> In the case of k2g the clocks are handled differently as when compared
>> with other keystones. Hence adding a separate compatible and match tables
>> accordingly.
>>
>> Signed-off-by: Keerthy <j-keerthy@ti.com>
>> ---
>> .../devicetree/bindings/gpio/gpio-davinci.txt | 2 +-
>> drivers/gpio/gpio-davinci.c | 45 ++++++++++++++++++++--
>> 2 files changed, 42 insertions(+), 5 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/gpio/gpio-davinci.txt b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt
>> index 5079ba7..a76abd2 100644
>> --- a/Documentation/devicetree/bindings/gpio/gpio-davinci.txt
>> +++ b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt
>> @@ -1,7 +1,7 @@
>> Davinci/Keystone GPIO controller bindings
>>
>> Required Properties:
>> -- compatible: should be "ti,dm6441-gpio", "ti,keystone-gpio"
>> +- compatible: should be "ti,dm6441-gpio", "ti,keystone-gpio", "ti,k2g-gpio"
>
> Is this "one of" or all? Seems line the former in which case please
> reformat to one per line.
It is One of. I will reformat.
>
>>
>> - reg: Physical base address of the controller and the size of memory mapped
>> registers.
^ permalink raw reply
* Re: [PATCH 2/5] drivers: gpio: Add support for multiple IPs
From: Keerthy @ 2016-10-27 3:42 UTC (permalink / raw)
To: Linus Walleij
Cc: Alexandre Courbot, Lokesh Vutla, Rob Herring,
linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux-OMAP,
Roger Quadros, Grygorii Strashko
In-Reply-To: <CACRpkdbsgM-yiWpiA5G35jQR8v3FO=Me+4rhe6TzE0qsWOJ8Ew-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Sunday 23 October 2016 04:02 PM, Linus Walleij wrote:
> On Wed, Oct 19, 2016 at 7:33 AM, Keerthy <j-keerthy-l0cyMroinI0@public.gmane.org> wrote:
>
>> From: Lokesh Vutla <lokeshvutla-l0cyMroinI0@public.gmane.org>
>>
>> Update GPIO driver to support Multiple GPIO IPs.
>>
>> Signed-off-by: Lokesh Vutla <lokeshvutla-l0cyMroinI0@public.gmane.org>
>> Signed-off-by: Keerthy <j-keerthy-l0cyMroinI0@public.gmane.org>
>
> This commit message is not at all describing what the patch is doing.
>
> What it does is bumping the GPIO pin offset in the Linux global
> GPIO number space with 32 for each new controller.
>
>> + static int bank_base;
>>
>> pdata = davinci_gpio_get_pdata(pdev);
>> if (!pdata) {
>> @@ -226,7 +227,8 @@ static int davinci_gpio_probe(struct platform_device *pdev)
>> chips[i].chip.direction_output = davinci_direction_out;
>> chips[i].chip.set = davinci_gpio_set;
>>
>> - chips[i].chip.base = base;
>> + chips[i].chip.base = bank_base;
>> + bank_base += 32;
>
> Why can you not rewrite the driver to pass -1 as base and
> get a dynamic allocation of GPIO numbers instead? Then
> you won't have this hairy problem.
Ok i will try that.
In case of k2g. There are 2 big GPIO modules GPIO0 and GPIO1.
GPIO0 comprises of 144 GPIOs
and GPIO1 has about 68 GPIOs. Wanted feedback from you on how this is
being modeled.
I am creating a controller for every 32 GPIOs under the big module each
containing a gpio_chip. Each 32 GPIOs chip has 2 banks of 16 GPIOs each.
Each 16 GPIO bank has an interrupt.
Is this modeling fine or do you think creating one chip with 144 pins
and another with 68 pins is a better way?
>
> Yours,
> Linus Walleij
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* RE: [v12, 5/8] soc: fsl: add GUTS driver for QorIQ platforms
From: Y.B. Lu @ 2016-10-27 4:34 UTC (permalink / raw)
To: Scott Wood, linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
Arnd Bergmann
Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Russell King, Bhupesh Sharma,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Santosh Shilimkar,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Jochen Friedrich, X.B. Xie, M.H. Lian,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
Rob Herring, linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Claudiu Manoil, Kumar Gala, Leo Li,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <1477501566.6812.9.camel-fOR+EgIDQEHk1uMJSBkQmQ@public.gmane.org>
Hi Scott,
> -----Original Message-----
> From: Scott Wood [mailto:oss@buserror.net]
> Sent: Thursday, October 27, 2016 1:06 AM
> To: Y.B. Lu; linux-mmc@vger.kernel.org; ulf.hansson@linaro.org; Arnd
> Bergmann
> Cc: linuxppc-dev@lists.ozlabs.org; devicetree@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org; linux-
> clk@vger.kernel.org; linux-i2c@vger.kernel.org; iommu@lists.linux-
> foundation.org; netdev@vger.kernel.org; Mark Rutland; Rob Herring;
> Russell King; Jochen Friedrich; Joerg Roedel; Claudiu Manoil; Bhupesh
> Sharma; Qiang Zhao; Kumar Gala; Santosh Shilimkar; Leo Li; X.B. Xie; M.H.
> Lian
> Subject: Re: [v12, 5/8] soc: fsl: add GUTS driver for QorIQ platforms
>
> On Wed, 2016-09-21 at 14:57 +0800, Yangbo Lu wrote:
> > diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig new
> > file mode 100644 index 0000000..b99764c
> > --- /dev/null
> > +++ b/drivers/soc/fsl/Kconfig
> > @@ -0,0 +1,19 @@
> > +#
> > +# Freescale SOC drivers
> > +#
> > +
> > +source "drivers/soc/fsl/qe/Kconfig"
> > +
> > +config FSL_GUTS
> > + bool "Freescale QorIQ GUTS driver"
> > + select SOC_BUS
> > + help
> > + The global utilities block controls power management, I/O device
> > + enabling, power-onreset(POR) configuration monitoring, alternate
> > + function selection for multiplexed signals,and clock control.
> > + This driver is to manage and access global utilities block.
> > + Initially only reading SVR and registering soc device are
> > supported.
> > + Other guts accesses, such as reading RCW, should eventually be
> > moved
> > + into this driver as well.
> > +
> > + If you want GUTS driver support, you should say Y here.
>
> This is user-enablable without dependencies, which means it will break
> some randconfigs. If this is to be enabled via select then remove the
> text after "bool".
[Lu Yangbo-B47093] Will enable it via select and remove text after 'bool'.
>
> > +/* SoC die attribute definition for QorIQ platform */ static const
> > +struct fsl_soc_die_attr fsl_soc_die[] = { #ifdef CONFIG_PPC
> > + /*
> > + * Power Architecture-based SoCs T Series
> > + */
> > +
> > + /* Die: T4240, SoC: T4240/T4160/T4080 */
> > + { .die = "T4240",
> > + .svr = 0x82400000,
> > + .mask = 0xfff00000,
> > + },
> > + /* Die: T1040, SoC: T1040/T1020/T1042/T1022 */
> > + { .die = "T1040",
> > + .svr = 0x85200000,
> > + .mask = 0xfff00000,
> > + },
> > + /* Die: T2080, SoC: T2080/T2081 */
> > + { .die = "T2080",
> > + .svr = 0x85300000,
> > + .mask = 0xfff00000,
> > + },
> > + /* Die: T1024, SoC: T1024/T1014/T1023/T1013 */
> > + { .die = "T1024",
> > + .svr = 0x85400000,
> > + .mask = 0xfff00000,
> > + },
> > +#endif /* CONFIG_PPC */
> > +#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_ARCH_LAYERSCAPE)
>
> Will this driver ever be probed on MXC? Why do we need these ifdefs at
> all?
[Lu Yangbo-B47093] Will remove them. In the previous version, we use too many members for soc definition, so I add #ifdef for ARCH.
CONFIG_ARCH_MXC was for ls1021a.
>
>
> > + /*
> > + * ARM-based SoCs LS Series
> > + */
> > +
> > + /* Die: LS1043A, SoC: LS1043A/LS1023A */
> > + { .die = "LS1043A",
> > + .svr = 0x87920000,
> > + .mask = 0xffff0000,
> > + },
> > + /* Die: LS2080A, SoC: LS2080A/LS2040A/LS2085A */
> > + { .die = "LS2080A",
> > + .svr = 0x87010000,
> > + .mask = 0xff3f0000,
> > + },
> > + /* Die: LS1088A, SoC: LS1088A/LS1048A/LS1084A/LS1044A */
> > + { .die = "LS1088A",
> > + .svr = 0x87030000,
> > + .mask = 0xff3f0000,
> > + },
> > + /* Die: LS1012A, SoC: LS1012A */
> > + { .die = "LS1012A",
> > + .svr = 0x87040000,
> > + .mask = 0xffff0000,
> > + },
> > + /* Die: LS1046A, SoC: LS1046A/LS1026A */
> > + { .die = "LS1046A",
> > + .svr = 0x87070000,
> > + .mask = 0xffff0000,
> > + },
> > + /* Die: LS2088A, SoC: LS2088A/LS2048A/LS2084A/LS2044A */
> > + { .die = "LS2088A",
> > + .svr = 0x87090000,
> > + .mask = 0xff3f0000,
> > + },
> > + /* Die: LS1021A, SoC: LS1021A/LS1020A/LS1022A
> > + * Note: Put this die at the end in cause of incorrect
> > identification
> > + */
> > + { .die = "LS1021A",
> > + .svr = 0x87000000,
> > + .mask = 0xfff00000,
> > + },
> > +#endif /* CONFIG_ARCH_MXC || CONFIG_ARCH_LAYERSCAPE */
>
> Instead of relying on ordering, add more bits to the mask so that there's
> no overlap. I think 0xfff70000 would work.
[Lu Yangbo-B47093] Ok, Will do that. Then we add 3 bits of 'Various Personalities' field for ls1021a die identification.
>
> > +out:
> > + kfree(soc_dev_attr.machine);
> > + kfree(soc_dev_attr.family);
> > + kfree(soc_dev_attr.soc_id);
> > + kfree(soc_dev_attr.revision);
> > + iounmap(guts->regs);
> > +out_free:
> > + kfree(guts);
> > + return ret;
> > +}
>
> Please use devm.
[Lu Yangbo-B47093] Sorry for forgetting this. Will do that and send out the new version soon.
Thanks for your comments.
>
> -Scott
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
^ permalink raw reply
* Re: [PATCH 5/6] arm64: dts: msm8994 SoC and Huawei Angler (Nexus 6P) support
From: Michael Scott @ 2016-10-27 5:33 UTC (permalink / raw)
To: Jeremy McNicoll, linux-arm-msm, linux-soc, devicetree
Cc: robh, andy.gross, sboyd, arnd, bjorn.andersson, mark.rutland
In-Reply-To: <1477394221-30963-6-git-send-email-jeremymc@redhat.com>
On 10/25/2016 04:17 AM, Jeremy McNicoll wrote:
> From: Bastian Köcher <mail@kchr.de>
>
> Initial device tree support for Qualcomm MSM8994 SoC and
> Huawei Angler / Google Nexus 6P support.
>
> The device tree is based on the Google 3.10 kernel tree.
>
> The device can be booted into the initrd with only one CPU running.
>
> Signed-off-by: Bastian Köcher <mail@kchr.de>
> [jeremymc@redhat.com: removed Kconfig, defconfig, move from Huawei to qcom dir]
> Signed-off-by: Jeremy McNicoll <jeremymc@redhat.com>
I tested this on my Nexus 6P so feel free to add my:
Tested-by: Michael Scott <michael.scott@linaro.org>
- Mike
> ---
> arch/arm64/boot/dts/qcom/Makefile | 1 +
> .../arm64/boot/dts/qcom/msm8994-angler-rev-101.dts | 40 ++++
> arch/arm64/boot/dts/qcom/msm8994-pins.dtsi | 38 ++++
> arch/arm64/boot/dts/qcom/msm8994-v2.0.dtsi | 32 +++
> arch/arm64/boot/dts/qcom/msm8994.dtsi | 218 +++++++++++++++++++++
> 5 files changed, 329 insertions(+)
> create mode 100644 arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
> create mode 100644 arch/arm64/boot/dts/qcom/msm8994-pins.dtsi
> create mode 100644 arch/arm64/boot/dts/qcom/msm8994-v2.0.dtsi
> create mode 100644 arch/arm64/boot/dts/qcom/msm8994.dtsi
>
> diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
> index 439e40e..cc0f02d 100644
> --- a/arch/arm64/boot/dts/qcom/Makefile
> +++ b/arch/arm64/boot/dts/qcom/Makefile
> @@ -2,6 +2,7 @@ dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc.dtb
> dtb-$(CONFIG_ARCH_QCOM) += apq8096-db820c.dtb
> dtb-$(CONFIG_ARCH_QCOM) += msm8916-mtp.dtb
> dtb-$(CONFIG_ARCH_QCOM) += msm8992-bullhead-rev-101.dtb
> +dtb-$(CONFIG_ARCH_QCOM) += msm8994-angler-rev-101.dtb
> dtb-$(CONFIG_ARCH_QCOM) += msm8996-mtp.dtb
>
> always := $(dtb-y)
> diff --git a/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
> new file mode 100644
> index 0000000..2fc68c4
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
> @@ -0,0 +1,40 @@
> +/* Copyright (c) 2015, Huawei Inc. All rights reserved.
> + * Copyright (c) 2016, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * 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.
> + */
> +
> +/dts-v1/;
> +
> +#include "msm8994-v2.0.dtsi"
> +
> +/ {
> + model = "HUAWEI MSM8994 ANGLER rev-1.01";
> + compatible = "qcom,msm8994";
> + /* required for bootloader to select correct board */
> + qcom,board-id = <8026 0>;
> +
> + aliases {
> + serial0 = &blsp1_uart2;
> + };
> +
> + chosen {
> + stdout-path = "serial0:115200n8";
> + };
> +
> + soc {
> + serial@f991e000 {
> + status = "okay";
> + pinctrl-names = "default", "sleep";
> + pinctrl-0 = <&blsp1_uart2_default>;
> + pinctrl-1 = <&blsp1_uart2_sleep>;
> + };
> + };
> +};
> diff --git a/arch/arm64/boot/dts/qcom/msm8994-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8994-pins.dtsi
> new file mode 100644
> index 0000000..0e4eea0
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/msm8994-pins.dtsi
> @@ -0,0 +1,38 @@
> +/*
> + * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * 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.
> + */
> +
> +&msmgpio {
> + blsp1_uart2_default: blsp1_uart2_default {
> + pinmux {
> + function = "blsp_uart2";
> + pins = "gpio4", "gpio5";
> + };
> + pinconf {
> + pins = "gpio4", "gpio5";
> + drive-strength = <16>;
> + bias-disable;
> + };
> + };
> +
> + blsp1_uart2_sleep: blsp1_uart2_sleep {
> + pinmux {
> + function = "gpio";
> + pins = "gpio4", "gpio5";
> + };
> + pinconf {
> + pins = "gpio4", "gpio5";
> + drive-strength = <2>;
> + bias-pull-down;
> + };
> + };
> +};
> diff --git a/arch/arm64/boot/dts/qcom/msm8994-v2.0.dtsi b/arch/arm64/boot/dts/qcom/msm8994-v2.0.dtsi
> new file mode 100644
> index 0000000..639781a
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/msm8994-v2.0.dtsi
> @@ -0,0 +1,32 @@
> +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * 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.
> + */
> +
> +/*
> + * As a general rule, only version-specific property overrides should be placed
> + * inside this file. Device definitions should be placed inside the msm8994.dtsi
> + * file.
> + */
> +
> +#include "msm8994.dtsi"
> +
> +/ {
> + model = "Qualcomm Technologies, Inc. MSM 8994v2.0";
> + compatible = "qcom,msm8994";
> + /* msm-id is required by bootloader for proper dt blob selection */
> + qcom,msm-id = <207 0x20000>;
> +
> +};
> +
> +/* Clock driver overrides */
> +&clock_gcc {
> + compatible = "qcom,gcc-8994v2";
> +};
> diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi
> new file mode 100644
> index 0000000..7efc159
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi
> @@ -0,0 +1,218 @@
> +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * 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.
> + */
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/clock/qcom,gcc-msm8994.h>
> +
> +/ {
> + model = "Qualcomm Technologies, Inc. MSM 8994";
> + compatible = "qcom,msm8994";
> + // msm-id and pmic-id are required by bootloader for
> + // proper selection of dt blob
> + qcom,msm-id = <207 0x0>;
> + qcom,pmic-id = <0x10009 0x1000A 0x0 0x0>;
> + interrupt-parent = <&intc>;
> +
> + #address-cells = <2>;
> + #size-cells = <2>;
> +
> + chosen { };
> +
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + cpu-map {
> + cluster0 {
> + core0 {
> + cpu = <&CPU0>;
> + };
> + };
> + };
> +
> + CPU0: cpu@0 {
> + device_type = "cpu";
> + compatible = "arm,cortex-a53", "arm,armv8";
> + reg = <0x0>;
> + next-level-cache = <&L2_0>;
> + L2_0: l2-cache {
> + compatible = "cache";
> + cache-level = <2>;
> + };
> + };
> + };
> +
> + timer {
> + compatible = "arm,armv8-timer";
> + interrupts = <1 2 0xff08>,
> + <1 3 0xff08>,
> + <1 4 0xff08>,
> + <1 1 0xff08>;
> + };
> +
> + soc: soc {
> +
> + #address-cells = <1>;
> + #size-cells = <1>;
> + ranges = <0 0 0 0xffffffff>;
> + compatible = "simple-bus";
> +
> + intc: interrupt-controller@f9000000 {
> + compatible = "qcom,msm-qgic2";
> + interrupt-controller;
> + #interrupt-cells = <3>;
> + reg = <0xf9000000 0x1000>,
> + <0xf9002000 0x1000>;
> + };
> +
> + timer@f9020000 {
> + #address-cells = <1>;
> + #size-cells = <1>;
> + ranges;
> + compatible = "arm,armv7-timer-mem";
> + reg = <0xf9020000 0x1000>;
> +
> + frame@f9021000 {
> + frame-number = <0>;
> + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
> + <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> + reg = <0xf9021000 0x1000>,
> + <0xf9022000 0x1000>;
> + };
> +
> + frame@f9023000 {
> + frame-number = <1>;
> + interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
> + reg = <0xf9023000 0x1000>;
> + status = "disabled";
> + };
> +
> + frame@f9024000 {
> + frame-number = <2>;
> + interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
> + reg = <0xf9024000 0x1000>;
> + status = "disabled";
> + };
> +
> + frame@f9025000 {
> + frame-number = <3>;
> + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
> + reg = <0xf9025000 0x1000>;
> + status = "disabled";
> + };
> +
> + frame@f9026000 {
> + frame-number = <4>;
> + interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
> + reg = <0xf9026000 0x1000>;
> + status = "disabled";
> + };
> +
> + frame@f9027000 {
> + frame-number = <5>;
> + interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
> + reg = <0xf9027000 0x1000>;
> + status = "disabled";
> + };
> +
> + frame@f9028000 {
> + frame-number = <6>;
> + interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
> + reg = <0xf9028000 0x1000>;
> + status = "disabled";
> + };
> + };
> +
> + restart@fc4ab000 {
> + compatible = "qcom,pshold";
> + reg = <0xfc4ab000 0x4>;
> + };
> +
> + msmgpio: pinctrl@fd510000 {
> + compatible = "qcom,msm8994-pinctrl";
> + reg = <0xfd510000 0x4000>;
> + interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
> + gpio-controller;
> + #gpio-cells = <2>;
> + interrupt-controller;
> + #interrupt-cells = <2>;
> + };
> +
> + blsp1_uart2: serial@f991e000 {
> + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
> + reg = <0xf991e000 0x1000>;
> + interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
> + status = "disabled";
> + clock-names = "core", "iface";
> + clocks = <&clock_gcc GCC_BLSP1_UART2_APPS_CLK>,
> + <&clock_gcc GCC_BLSP1_AHB_CLK>;
> + };
> +
> + tcsr_mutex_regs: syscon@fd484000 {
> + compatible = "syscon";
> + reg = <0xfd484000 0x2000>;
> + };
> +
> + tcsr_mutex: hwlock {
> + compatible = "qcom,tcsr-mutex";
> + syscon = <&tcsr_mutex_regs 0 0x80>;
> + #hwlock-cells = <1>;
> + };
> +
> + qcom,smem@6a00000 {
> + compatible = "qcom,smem";
> + memory-region = <&smem_mem>;
> + hwlocks = <&tcsr_mutex 3>;
> + };
> +
> + clock_gcc: qcom,gcc@fc400000 {
> + compatible = "qcom,gcc-8994";
> + #clock-cells = <1>;
> + #reset-cells = <1>;
> + #power-domain-cells = <1>;
> + reg = <0xfc400000 0x2000>;
> + };
> + };
> +
> + memory {
> + device_type = "memory";
> + // We expect the bootloader to fill in the reg
> + reg = <0 0 0 0>;
> + };
> +
> + clocks {
> + xo_board: xo_board {
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <19200000>;
> + };
> +
> + sleep_clk: sleep_clk {
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <32768>;
> + };
> + };
> +
> + reserved-memory {
> + #address-cells = <2>;
> + #size-cells = <2>;
> + ranges;
> +
> + smem_mem: smem_region@0x6a00000 {
> + reg = <0x0 0x6a00000 0x0 0x200000>;
> + no-map;
> + };
> + };
> +};
> +
> +
> +#include "msm8994-pins.dtsi"
^ permalink raw reply
* [PATCH 0/3] ARM: dts: am33xx: Add clock info to rtc nodes
From: Keerthy @ 2016-10-27 5:48 UTC (permalink / raw)
To: tony-4v6yS6AI5VpBDgjK7y7TUQ
Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
j-keerthy-l0cyMroinI0, t-kristo-l0cyMroinI0
The series adds the clock info to rtc node.
Boot tested and checked for rtc ticking on am335x-boneblack, am335x-bone
am437x-gp-evm.
Keerthy (3):
ARM: dts: AM335X-bone-common: Add the internal and external clock
nodes for rtc
ARM: dts: AM335X-evm: Add the internal and external clock nodes for
rtc
ARM: dts: AM335X-evmsk: Add the internal and external clock nodes for
rtc
arch/arm/boot/dts/am335x-bone-common.dtsi | 5 +++++
arch/arm/boot/dts/am335x-evm.dts | 5 +++++
arch/arm/boot/dts/am335x-evmsk.dts | 5 +++++
arch/arm/boot/dts/am33xx.dtsi | 2 ++
4 files changed, 17 insertions(+)
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 1/3] ARM: dts: AM335X-bone-common: Add the internal and external clock nodes for rtc
From: Keerthy @ 2016-10-27 5:48 UTC (permalink / raw)
To: tony-4v6yS6AI5VpBDgjK7y7TUQ
Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
j-keerthy-l0cyMroinI0, t-kristo-l0cyMroinI0
In-Reply-To: <1477547288-5041-1-git-send-email-j-keerthy-l0cyMroinI0@public.gmane.org>
rtc can either be supplied from internal 32k clock or external crystal
generated 32k clock. Internal clock is SoC specific and the external
clock is board dependent. Assigning the corresponding clocks.
Signed-off-by: Keerthy <j-keerthy-l0cyMroinI0@public.gmane.org>
---
arch/arm/boot/dts/am335x-bone-common.dtsi | 5 +++++
arch/arm/boot/dts/am33xx.dtsi | 2 ++
2 files changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
index 007b5e5..ca9f7ce 100644
--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
@@ -393,3 +393,8 @@
&sham {
status = "okay";
};
+
+&rtc {
+ clocks = <&clk_32768_ck>, <&clkdiv32k_ick>;
+ clock-names = "ext-clk", "int-clk";
+};
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 194d884..d52fa1c 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -505,6 +505,8 @@
interrupts = <75
76>;
ti,hwmods = "rtc";
+ clocks = <&clkdiv32k_ick>;
+ clock-names = "int-clk";
};
spi0: spi@48030000 {
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 2/3] ARM: dts: AM335X-evm: Add the internal and external clock nodes for rtc
From: Keerthy @ 2016-10-27 5:48 UTC (permalink / raw)
To: tony-4v6yS6AI5VpBDgjK7y7TUQ
Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
j-keerthy-l0cyMroinI0, t-kristo-l0cyMroinI0
In-Reply-To: <1477547288-5041-1-git-send-email-j-keerthy-l0cyMroinI0@public.gmane.org>
rtc can either be supplied from internal 32k clock or external crystal
generated 32k clock. Internal clock is SoC specific and the external
clock is board dependent. Assigning the corresponding clocks.
Signed-off-by: Keerthy <j-keerthy-l0cyMroinI0@public.gmane.org>
---
arch/arm/boot/dts/am335x-evm.dts | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index e82432c..c2186ec 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -783,3 +783,8 @@
pinctrl-names = "default";
pinctrl-0 = <&dcan1_pins_default>;
};
+
+&rtc {
+ clocks = <&clk_32768_ck>, <&clkdiv32k_ick>;
+ clock-names = "ext-clk", "int-clk";
+};
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 3/3] ARM: dts: AM335X-evmsk: Add the internal and external clock nodes for rtc
From: Keerthy @ 2016-10-27 5:48 UTC (permalink / raw)
To: tony-4v6yS6AI5VpBDgjK7y7TUQ
Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
j-keerthy-l0cyMroinI0, t-kristo-l0cyMroinI0
In-Reply-To: <1477547288-5041-1-git-send-email-j-keerthy-l0cyMroinI0@public.gmane.org>
rtc can either be supplied from internal 32k clock or external crystal
generated 32k clock. Internal clock is SoC specific and the external
clock is board dependent. Assigning the corresponding clocks.
Signed-off-by: Keerthy <j-keerthy-l0cyMroinI0@public.gmane.org>
---
arch/arm/boot/dts/am335x-evmsk.dts | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts
index 975c36e..e2548d1 100644
--- a/arch/arm/boot/dts/am335x-evmsk.dts
+++ b/arch/arm/boot/dts/am335x-evmsk.dts
@@ -715,3 +715,8 @@
blue-and-red-wiring = "crossed";
};
+
+&rtc {
+ clocks = <&clk_32768_ck>, <&clkdiv32k_ick>;
+ clock-names = "ext-clk", "int-clk";
+};
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 09/10] pwm: imx: doc: Update imx-pwm.txt documentation entry
From: Lukasz Majewski @ 2016-10-27 6:33 UTC (permalink / raw)
To: Thierry Reding, Stefan Agner, Boris Brezillon
Cc: linux-pwm, linux-kernel, Fabio Estevam, Fabio Estevam,
Lothar Wassmann, Bhuvanchandra DV, kernel, Rob Herring,
Mark Rutland, devicetree, Lukasz Majewski
The imx-pwm.txt documentation update as a preparation for polarity
support.
Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Signed-off-by: Lukasz Majewski <l.majewski@majess.pl>
---
Changes for v2:
- New patch
---
Documentation/devicetree/bindings/pwm/imx-pwm.txt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/pwm/imx-pwm.txt b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
index e00c2e9..c61bdf8 100644
--- a/Documentation/devicetree/bindings/pwm/imx-pwm.txt
+++ b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
@@ -6,8 +6,8 @@ Required properties:
- "fsl,imx1-pwm" for PWM compatible with the one integrated on i.MX1
- "fsl,imx27-pwm" for PWM compatible with the one integrated on i.MX27
- reg: physical base address and length of the controller's registers
-- #pwm-cells: should be 2. See pwm.txt in this directory for a description of
- the cells format.
+- #pwm-cells: 2 for i.MX1 and 3 for i.MX27 and newer SoCs. See pwm.txt
+ in this directory for a description of the cells format.
- clocks : Clock specifiers for both ipg and per clocks.
- clock-names : Clock names should include both "ipg" and "per"
See the clock consumer binding,
@@ -17,7 +17,7 @@ See the clock consumer binding,
Example:
pwm1: pwm@53fb4000 {
- #pwm-cells = <2>;
+ #pwm-cells = <3>;
compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
reg = <0x53fb4000 0x4000>;
clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
--
2.1.4
^ permalink raw reply related
* Re: [PATCH v2 1/8] drm/bridge: rgb-to-vga: Support an enable GPIO
From: Archit Taneja @ 2016-10-27 6:40 UTC (permalink / raw)
To: Chen-Yu Tsai, Laurent Pinchart
Cc: Maxime Ripard, David Airlie, Rob Herring, Mark Rutland,
devicetree, linux-sunxi, dri-devel, linux-kernel,
linux-arm-kernel
In-Reply-To: <CAGb2v64=c5PFx+qJkfPeKYFQYLYoYfWgjg49O4Es5qVjuyf5gg@mail.gmail.com>
On 10/25/2016 02:29 PM, Chen-Yu Tsai wrote:
> On Tue, Oct 25, 2016 at 4:09 PM, Archit Taneja <architt@codeaurora.org> wrote:
>> Hi,
>>
>> On 10/20/2016 09:13 AM, Chen-Yu Tsai wrote:
>>>
>>> Some rgb-to-vga bridges have an enable GPIO, either directly tied to
>>> an enable pin on the bridge IC, or indirectly controlling a power
>>> switch.
>>>
>>> Add support for it.
>>
>>
>> Does the bridge on your platform have an active/passive DAC, or is it a
>> smarter encoder chip that is capable of doing more? If so, it might be
>> good to have a separate DT compatible string to it, like what's done
>> in the patch titled:
>>
>> drm: bridge: vga-dac: Add adi,adv7123 compatible string
>>
>> so that we can switch to a different driver later if needed.
>
> The chip is GM7123. It is not configurable. It just takes the LCD RGB/SYNC
> signals and converts them to analog. The only things you can change are
> putting it into sleep mode and tweaking the output drive strength by
Is sleep mode the thing that's controlled by this gpio?
> changing the external reference resistor. The latter would be a hardware
> design decision. I would say this qualifies as "dumb".
Yeah, I agree. I'd want feedback from Laurent too, since he had comments
on the usage of the original dumb-vga-dac driver.
>
> I revisited the board schematics, and the enable GPIO actually toggles
> an external LDO regulator. So this might be better modeled as a regulator
> supply?
If you model it as a regulator, how would you toggle the GPIO on your
platform?
Looking at the chip pin out, there is a 3.3V VDD supply needed for the
chip, so it would be good to have an optional 'power' regulator supply
anyway.
Archit
>
>
> Thanks
> ChenYu
>
>>
>> Thanks,
>> Archit
>>
>>
>>>
>>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>>> ---
>>> .../bindings/display/bridge/dumb-vga-dac.txt | 2 ++
>>> drivers/gpu/drm/bridge/dumb-vga-dac.c | 28
>>> ++++++++++++++++++++++
>>> 2 files changed, 30 insertions(+)
>>>
>>> diff --git
>>> a/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
>>> b/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
>>> index 003bc246a270..d3484822bf77 100644
>>> --- a/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
>>> +++ b/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
>>> @@ -16,6 +16,8 @@ graph bindings specified in
>>> Documentation/devicetree/bindings/graph.txt.
>>> - Video port 0 for RGB input
>>> - Video port 1 for VGA output
>>>
>>> +Optional properties:
>>> +- enable-gpios: GPIO pin to enable or disable the bridge
>>>
>>> Example
>>> -------
>>> diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c
>>> b/drivers/gpu/drm/bridge/dumb-vga-dac.c
>>> index afec232185a7..b487e5e9b56d 100644
>>> --- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
>>> +++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
>>> @@ -10,6 +10,7 @@
>>> * the License, or (at your option) any later version.
>>> */
>>>
>>> +#include <linux/gpio/consumer.h>
>>> #include <linux/module.h>
>>> #include <linux/of_graph.h>
>>>
>>> @@ -23,6 +24,7 @@ struct dumb_vga {
>>> struct drm_connector connector;
>>>
>>> struct i2c_adapter *ddc;
>>> + struct gpio_desc *enable_gpio;
>>> };
>>>
>>> static inline struct dumb_vga *
>>> @@ -124,8 +126,26 @@ static int dumb_vga_attach(struct drm_bridge *bridge)
>>> return 0;
>>> }
>>>
>>> +static void dumb_vga_enable(struct drm_bridge *bridge)
>>> +{
>>> + struct dumb_vga *vga = drm_bridge_to_dumb_vga(bridge);
>>> +
>>> + if (vga->enable_gpio)
>>> + gpiod_set_value_cansleep(vga->enable_gpio, 1);
>>> +}
>>> +
>>> +static void dumb_vga_disable(struct drm_bridge *bridge)
>>> +{
>>> + struct dumb_vga *vga = drm_bridge_to_dumb_vga(bridge);
>>> +
>>> + if (vga->enable_gpio)
>>> + gpiod_set_value_cansleep(vga->enable_gpio, 0);
>>> +}
>>> +
>>> static const struct drm_bridge_funcs dumb_vga_bridge_funcs = {
>>> .attach = dumb_vga_attach,
>>> + .enable = dumb_vga_enable,
>>> + .disable = dumb_vga_disable,
>>> };
>>>
>>> static struct i2c_adapter *dumb_vga_retrieve_ddc(struct device *dev)
>>> @@ -169,6 +189,14 @@ static int dumb_vga_probe(struct platform_device
>>> *pdev)
>>> return -ENOMEM;
>>> platform_set_drvdata(pdev, vga);
>>>
>>> + vga->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
>>> + GPIOD_OUT_LOW);
>>> + if (IS_ERR(vga->enable_gpio)) {
>>> + ret = PTR_ERR(vga->enable_gpio);
>>> + dev_err(&pdev->dev, "failed to request GPIO: %d\n", ret);
>>> + return ret;
>>> + }
>>> +
>>> vga->ddc = dumb_vga_retrieve_ddc(&pdev->dev);
>>> if (IS_ERR(vga->ddc)) {
>>> if (PTR_ERR(vga->ddc) == -ENODEV) {
>>>
>>
>> --
>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>> a Linux Foundation Collaborative Project
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH v2 1/8] drm/bridge: rgb-to-vga: Support an enable GPIO
From: Chen-Yu Tsai @ 2016-10-27 6:52 UTC (permalink / raw)
To: Archit Taneja
Cc: Chen-Yu Tsai, Laurent Pinchart, Maxime Ripard, David Airlie,
Rob Herring, Mark Rutland, devicetree, linux-sunxi, dri-devel,
linux-kernel, linux-arm-kernel
In-Reply-To: <87ca071d-c396-25b3-aff4-c838c9003f94-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
On Thu, Oct 27, 2016 at 2:40 PM, Archit Taneja <architt-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> wrote:
>
>
> On 10/25/2016 02:29 PM, Chen-Yu Tsai wrote:
>>
>> On Tue, Oct 25, 2016 at 4:09 PM, Archit Taneja <architt-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
>> wrote:
>>>
>>> Hi,
>>>
>>> On 10/20/2016 09:13 AM, Chen-Yu Tsai wrote:
>>>>
>>>>
>>>> Some rgb-to-vga bridges have an enable GPIO, either directly tied to
>>>> an enable pin on the bridge IC, or indirectly controlling a power
>>>> switch.
>>>>
>>>> Add support for it.
>>>
>>>
>>>
>>> Does the bridge on your platform have an active/passive DAC, or is it a
>>> smarter encoder chip that is capable of doing more? If so, it might be
>>> good to have a separate DT compatible string to it, like what's done
>>> in the patch titled:
>>>
>>> drm: bridge: vga-dac: Add adi,adv7123 compatible string
>>>
>>> so that we can switch to a different driver later if needed.
>>
>>
>> The chip is GM7123. It is not configurable. It just takes the LCD RGB/SYNC
>> signals and converts them to analog. The only things you can change are
>> putting it into sleep mode and tweaking the output drive strength by
>
>
> Is sleep mode the thing that's controlled by this gpio?
Not on this particular board. The gpio controls the external LDO that
supplies 3.3V to VDD.
>
>> changing the external reference resistor. The latter would be a hardware
>> design decision. I would say this qualifies as "dumb".
>
>
> Yeah, I agree. I'd want feedback from Laurent too, since he had comments
> on the usage of the original dumb-vga-dac driver.
>
>>
>> I revisited the board schematics, and the enable GPIO actually toggles
>> an external LDO regulator. So this might be better modeled as a regulator
>> supply?
>
>
> If you model it as a regulator, how would you toggle the GPIO on your
> platform?
>
> Looking at the chip pin out, there is a 3.3V VDD supply needed for the
> chip, so it would be good to have an optional 'power' regulator supply
> anyway.
Yes, that it what I plan to do. I'll drop the enable-gpios property,
and add a power-supply property for the regulator.
Regards
ChenYu
>
> Archit
>
>
>>
>>
>> Thanks
>> ChenYu
>>
>>>
>>> Thanks,
>>> Archit
>>>
>>>
>>>>
>>>> Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
>>>> ---
>>>> .../bindings/display/bridge/dumb-vga-dac.txt | 2 ++
>>>> drivers/gpu/drm/bridge/dumb-vga-dac.c | 28
>>>> ++++++++++++++++++++++
>>>> 2 files changed, 30 insertions(+)
>>>>
>>>> diff --git
>>>> a/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
>>>> b/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
>>>> index 003bc246a270..d3484822bf77 100644
>>>> --- a/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
>>>> +++ b/Documentation/devicetree/bindings/display/bridge/dumb-vga-dac.txt
>>>> @@ -16,6 +16,8 @@ graph bindings specified in
>>>> Documentation/devicetree/bindings/graph.txt.
>>>> - Video port 0 for RGB input
>>>> - Video port 1 for VGA output
>>>>
>>>> +Optional properties:
>>>> +- enable-gpios: GPIO pin to enable or disable the bridge
>>>>
>>>> Example
>>>> -------
>>>> diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c
>>>> b/drivers/gpu/drm/bridge/dumb-vga-dac.c
>>>> index afec232185a7..b487e5e9b56d 100644
>>>> --- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
>>>> +++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
>>>> @@ -10,6 +10,7 @@
>>>> * the License, or (at your option) any later version.
>>>> */
>>>>
>>>> +#include <linux/gpio/consumer.h>
>>>> #include <linux/module.h>
>>>> #include <linux/of_graph.h>
>>>>
>>>> @@ -23,6 +24,7 @@ struct dumb_vga {
>>>> struct drm_connector connector;
>>>>
>>>> struct i2c_adapter *ddc;
>>>> + struct gpio_desc *enable_gpio;
>>>> };
>>>>
>>>> static inline struct dumb_vga *
>>>> @@ -124,8 +126,26 @@ static int dumb_vga_attach(struct drm_bridge
>>>> *bridge)
>>>> return 0;
>>>> }
>>>>
>>>> +static void dumb_vga_enable(struct drm_bridge *bridge)
>>>> +{
>>>> + struct dumb_vga *vga = drm_bridge_to_dumb_vga(bridge);
>>>> +
>>>> + if (vga->enable_gpio)
>>>> + gpiod_set_value_cansleep(vga->enable_gpio, 1);
>>>> +}
>>>> +
>>>> +static void dumb_vga_disable(struct drm_bridge *bridge)
>>>> +{
>>>> + struct dumb_vga *vga = drm_bridge_to_dumb_vga(bridge);
>>>> +
>>>> + if (vga->enable_gpio)
>>>> + gpiod_set_value_cansleep(vga->enable_gpio, 0);
>>>> +}
>>>> +
>>>> static const struct drm_bridge_funcs dumb_vga_bridge_funcs = {
>>>> .attach = dumb_vga_attach,
>>>> + .enable = dumb_vga_enable,
>>>> + .disable = dumb_vga_disable,
>>>> };
>>>>
>>>> static struct i2c_adapter *dumb_vga_retrieve_ddc(struct device *dev)
>>>> @@ -169,6 +189,14 @@ static int dumb_vga_probe(struct platform_device
>>>> *pdev)
>>>> return -ENOMEM;
>>>> platform_set_drvdata(pdev, vga);
>>>>
>>>> + vga->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
>>>> + GPIOD_OUT_LOW);
>>>> + if (IS_ERR(vga->enable_gpio)) {
>>>> + ret = PTR_ERR(vga->enable_gpio);
>>>> + dev_err(&pdev->dev, "failed to request GPIO: %d\n",
>>>> ret);
>>>> + return ret;
>>>> + }
>>>> +
>>>> vga->ddc = dumb_vga_retrieve_ddc(&pdev->dev);
>>>> if (IS_ERR(vga->ddc)) {
>>>> if (PTR_ERR(vga->ddc) == -ENODEV) {
>>>>
>>>
>>> --
>>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>>> a Linux Foundation Collaborative Project
>
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH v4 0/7] Add R8A7743/SK-RZG1M board support
From: Simon Horman @ 2016-10-27 7:06 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Sergei Shtylyov, Linux-Renesas, Rob Herring, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Magnus Damm,
Russell King,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <CAMuHMdWQegsEf_C=UGXpQiEAX0YQqy335teuvCZxBY6C=7QozA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Wed, Oct 26, 2016 at 03:27:14PM +0200, Geert Uytterhoeven wrote:
> On Wed, Oct 26, 2016 at 3:23 PM, Sergei Shtylyov
> <sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org> wrote:
> > On 10/26/2016 03:08 PM, Geert Uytterhoeven wrote:
> >>> Here's the set of 8 patches against Simon Horman's 'renesas.git'
> >>> repo's
> >>> 'renesas-devel-20161021-v4.9-rc1' tag. I'm adding the device tree support
> >>> for
> >>> the R8A7743-based SK-RZG1M board. The SoC is close to R8A7791 and the
> >>> board
> >>> seems identical to the R8A7791/Porter board. The device tree patches
> >>> depend on
> >>> the R8A7743 CPG/MSSR driver series just posted in order to compile and
> >>> work.
> >>
> >>
> >> They depend only on "[PATCH v3 1/2] ARM: shmobile: r8a7743: add CPG clock
> >> index macros" of that series, right?
> >>
> >> "[PATCH v3 2/2] clk: renesas: cpg-mssr: add R8A7743 support" is not
> >> needed,
> >
> > How would "clocks" props _work_ without this patch?
>
> Sorry, I was focusing too much on "compile"...
>
> Got my coke, switching brain to overdrive mode...
As we are talking about adding support for a new SoC I would be happy
to queue up code in my tree that compiles under the assumption that
in v4.10 the bits to make it run will appear in other branches.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2 1/4] arm64: arch_timer: Add device tree binding for hisilicon-161601 erratum
From: Ding Tianhong @ 2016-10-27 7:34 UTC (permalink / raw)
To: catalin.marinas, will.deacon, marc.zyngier, mark.rutland, oss,
devicetree, shawnguo, stuart.yoder, linux-arm-kernel, linuxarm
Cc: Ding Tianhong
This erratum describes a bug in logic outside the core, so MIDR can't be
used to identify its presence, and reading an SoC-specific revision
register from common arch timer code would be awkward. So, describe it
in the device tree.
v2: Use the new erratum name and update the description.
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
Documentation/devicetree/bindings/arm/arch_timer.txt | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/arch_timer.txt b/Documentation/devicetree/bindings/arm/arch_timer.txt
index ef5fbe9..c27b2c4 100644
--- a/Documentation/devicetree/bindings/arm/arch_timer.txt
+++ b/Documentation/devicetree/bindings/arm/arch_timer.txt
@@ -31,6 +31,14 @@ to deliver its interrupts via SPIs.
This also affects writes to the tval register, due to the implicit
counter read.
+- hisilicon,erratum-161601 : A boolean property. Indicates the presence of
+ erratum 161601, which says that reading the counter is unreliable unless
+ reading twice on the register and the value of the second read is larger
+ than the first by less than 32. If the verification is unsuccessful, then
+ discard the value of this read and repeat this procedure until the verification
+ is successful. This also affects writes to the tval register, due to the
+ implicit counter read.
+
** Optional properties:
- arm,cpu-registers-not-fw-configured : Firmware does not initialize
--
1.9.0
^ permalink raw reply related
* [PATCH v2 2/4] arm64: arch_timer: Introduce a generic erratum handing mechanism for fsl-a008585
From: Ding Tianhong @ 2016-10-27 7:34 UTC (permalink / raw)
To: catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
marc.zyngier-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
oss-fOR+EgIDQEHk1uMJSBkQmQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
shawnguo-DgEjT+Ai2ygdnm+yROfE0A, stuart.yoder-3arQi8VN3Tc,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linuxarm-hv44wF8Li93QT0dZR+AlfA
Cc: Ding Tianhong
In-Reply-To: <1477553651-13428-1-git-send-email-dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
The workaround for hisilicon,161601 will check the return value of the system counter
by different way, in order to distinguish with the fsl-a008585 workaround, introduce
a new generic erratum handing mechanism for fsl-a008585 and rename some functions.
v2: Introducing a new generic erratum handling mechanism for fsl erratum a008585.
Signed-off-by: Ding Tianhong <dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
arch/arm64/include/asm/arch_timer.h | 20 +++++++++-----
drivers/clocksource/arm_arch_timer.c | 51 +++++++++++++++++++++---------------
2 files changed, 43 insertions(+), 28 deletions(-)
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index eaa5bbe..118719d8 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -31,15 +31,21 @@
#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585)
extern struct static_key_false arch_timer_read_ool_enabled;
-#define needs_fsl_a008585_workaround() \
+#define needs_timer_erratum_workaround() \
static_branch_unlikely(&arch_timer_read_ool_enabled)
#else
-#define needs_fsl_a008585_workaround() false
+#define needs_timer_erratum_workaround() false
#endif
-u32 __fsl_a008585_read_cntp_tval_el0(void);
-u32 __fsl_a008585_read_cntv_tval_el0(void);
-u64 __fsl_a008585_read_cntvct_el0(void);
+
+struct arch_timer_erratum_workaround {
+ int erratum;
+ u32 (*read_cntp_tval_el0)(void);
+ u32 (*read_cntv_tval_el0)(void);
+ u64 (*read_cntvct_el0)(void);
+};
+
+extern struct arch_timer_erratum_workaround *erratum_workaround;
/*
* The number of retries is an arbitrary value well beyond the highest number
@@ -62,8 +68,8 @@ u64 __fsl_a008585_read_cntvct_el0(void);
#define arch_timer_reg_read_stable(reg) \
({ \
u64 _val; \
- if (needs_fsl_a008585_workaround()) \
- _val = __fsl_a008585_read_##reg(); \
+ if (needs_timer_erratum_workaround()) \
+ _val = erratum_workaround->read_##reg(); \
else \
_val = read_sysreg(reg); \
_val; \
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 73c487d..e4f7fa1 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -95,10 +95,32 @@ early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg);
*/
#ifdef CONFIG_FSL_ERRATUM_A008585
+struct arch_timer_erratum_workaround *erratum_workaround = NULL;
+
DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
-static int fsl_a008585_enable = -1;
+
+static u32 fsl_a008585_read_cntp_tval_el0(void)
+{
+ return __fsl_a008585_read_reg(cntp_tval_el0);
+}
+
+static u32 fsl_a008585_read_cntv_tval_el0(void)
+{
+ return __fsl_a008585_read_reg(cntv_tval_el0);
+}
+
+static u64 fsl_a008585_read_cntvct_el0(void)
+{
+ return __fsl_a008585_read_reg(cntvct_el0);
+}
+
+static struct arch_timer_erratum_workaround arch_timer_fsl_a008585 = {
+ .read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
+ .read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
+ .read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
+};
static int __init early_fsl_a008585_cfg(char *buf)
{
@@ -109,26 +131,12 @@ static int __init early_fsl_a008585_cfg(char *buf)
if (ret)
return ret;
- fsl_a008585_enable = val;
+ if (val)
+ erratum_workaround = &arch_timer_fsl_a008585;
+
return 0;
}
early_param("clocksource.arm_arch_timer.fsl-a008585", early_fsl_a008585_cfg);
-
-u32 __fsl_a008585_read_cntp_tval_el0(void)
-{
- return __fsl_a008585_read_reg(cntp_tval_el0);
-}
-
-u32 __fsl_a008585_read_cntv_tval_el0(void)
-{
- return __fsl_a008585_read_reg(cntv_tval_el0);
-}
-
-u64 __fsl_a008585_read_cntvct_el0(void)
-{
- return __fsl_a008585_read_reg(cntvct_el0);
-}
-EXPORT_SYMBOL(__fsl_a008585_read_cntvct_el0);
#endif /* CONFIG_FSL_ERRATUM_A008585 */
static __always_inline
@@ -891,9 +899,10 @@ static int __init arch_timer_of_init(struct device_node *np)
arch_timer_c3stop = !of_property_read_bool(np, "always-on");
#ifdef CONFIG_FSL_ERRATUM_A008585
- if (fsl_a008585_enable < 0)
- fsl_a008585_enable = of_property_read_bool(np, "fsl,erratum-a008585");
- if (fsl_a008585_enable) {
+ if (!erratum_workaround && of_property_read_bool(np, "fsl,erratum-a008585"))
+ erratum_workaround = &arch_timer_fsl_a008585;
+
+ if (erratum_workaround) {
static_branch_enable(&arch_timer_read_ool_enabled);
pr_info("Enabling workaround for FSL erratum A-008585\n");
}
--
1.9.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 3/4] arm64: arch_timer: Work around Erratum Hisilicon-161601
From: Ding Tianhong @ 2016-10-27 7:34 UTC (permalink / raw)
To: catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
marc.zyngier-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
oss-fOR+EgIDQEHk1uMJSBkQmQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
shawnguo-DgEjT+Ai2ygdnm+yROfE0A, stuart.yoder-3arQi8VN3Tc,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linuxarm-hv44wF8Li93QT0dZR+AlfA
Cc: Ding Tianhong
In-Reply-To: <1477553651-13428-1-git-send-email-dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Erratum Hisilicon-161601 says that the ARM generic timer counter "has the
potential to contain an erroneous value when the timer value changes".
Accesses to TVAL (both read and write) are also affected due to the implicit counter
read. Accesses to CVAL are not affected.
The workaround is to reread the system count registers until the value of the second
read is larger than the first one by less than 32, the system counter can be guaranteed
not to return wrong value twice by back-to-back read and the error value is always larger
than the correct one by 32. Writes to TVAL are replaced with an equivalent write to CVAL.
The workaround is enabled if the hisilicon,erratum-161601 property is found in
the timer node in the device tree. This can be overridden with the
clocksource.arm_arch_timer.hisilicon-161601 boot parameter, which allows KVM
users to enable the workaround until a mechanism is implemented to
automatically communicate this information.
Fix some description for fsl erratum a008585.
v2: Significant rework based on feedback, including seperate the fsl erratum a008585
to another patch, update the erratum name and remove unwanted code.
Signed-off-by: Ding Tianhong <dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
Documentation/arm64/silicon-errata.txt | 1 +
Documentation/kernel-parameters.txt | 9 ++++
arch/arm64/include/asm/arch_timer.h | 28 ++++++++++-
drivers/clocksource/Kconfig | 14 +++++-
drivers/clocksource/arm_arch_timer.c | 88 ++++++++++++++++++++++++++--------
5 files changed, 118 insertions(+), 22 deletions(-)
diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
index 405da11..70c5d5e 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -63,3 +63,4 @@ stable kernels.
| Cavium | ThunderX SMMUv2 | #27704 | N/A |
| | | | |
| Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 |
+| Hisilicon | Hip05/Hip06/Hip07 | #161601 | HISILICON_ERRATUM_161601|
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 6fa1d8a..735b4b6 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -707,6 +707,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
erratum. If unspecified, the workaround is
enabled based on the device tree.
+ clocksource.arm_arch_timer.hisilicon-161601=
+ [ARM64]
+ Format: <bool>
+ Enable/disable the workaround of Hisilicon
+ erratum 161601. This can be useful for KVM
+ guests, if the guest device tree doesn't show the
+ erratum. If unspecified, the workaround is
+ enabled based on the device tree.
+
clearcpuid=BITNUM [X86]
Disable CPUID feature X for the kernel. See
arch/x86/include/asm/cpufeatures.h for the valid bit
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 118719d8..49b3041 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -29,7 +29,7 @@
#include <clocksource/arm_arch_timer.h>
-#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585)
+#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
extern struct static_key_false arch_timer_read_ool_enabled;
#define needs_timer_erratum_workaround() \
static_branch_unlikely(&arch_timer_read_ool_enabled)
@@ -65,11 +65,35 @@ extern struct arch_timer_erratum_workaround *erratum_workaround;
_new; \
})
+
+
+/*
+ * The number of retries is an arbitrary value well beyond the highest number
+ * of iterations the loop has been observed to take.
+ * Verify whether the value of the second read is larger than the first by
+ * less than 32 is the only way to confirm the value is correct, the system
+ * counter can be guaranteed not to return wrong value twice by back-to-back read
+ * and the error value is always larger than the correct one by 32.
+ */
+#define __hisi_161601_read_reg(reg) ({ \
+ u64 _old, _new; \
+ int _retries = 200; \
+ \
+ do { \
+ _old = read_sysreg(reg); \
+ _new = read_sysreg(reg); \
+ _retries--; \
+ } while (unlikely((_new - _old) >> 5) && _retries); \
+ \
+ WARN_ON_ONCE(!_retries); \
+ _new; \
+})
+
#define arch_timer_reg_read_stable(reg) \
({ \
u64 _val; \
if (needs_timer_erratum_workaround()) \
- _val = erratum_workaround->read_##reg(); \
+ _val = erratum_workaround->read_##reg();\
else \
_val = read_sysreg(reg); \
_val; \
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 8a753fd..4aafb6a 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -312,8 +312,20 @@ config FSL_ERRATUM_A008585
help
This option enables a workaround for Freescale/NXP Erratum
A-008585 ("ARM generic timer may contain an erroneous
- value"). The workaround will only be active if the
+ value"). The workaround will be active if the
fsl,erratum-a008585 property is found in the timer node.
+ This can be overridden with the clocksource.arm_arch_timer.fsl-a008585
+ boot parameter.
+
+config HISILICON_ERRATUM_161601
+ bool "Workaround for Hisilicon Erratum 161601"
+ default y
+ depends on ARM_ARCH_TIMER && ARM64
+ help
+ This option enables a workaround for Hisilicon Erratum
+ 161601. The workaround will be active if the hisilicon,erratum-161601
+ property is found in the timer node. This can be overridden with
+ the clocksource.arm_arch_timer.hisilicon-161601 boot parameter.
config ARM_GLOBAL_TIMER
bool "Support for the ARM global timer" if COMPILE_TEST
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index e4f7fa1..89f1895 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -94,13 +94,14 @@ early_param("clocksource.arm_arch_timer.evtstrm", early_evtstrm_cfg);
* Architected system timer support.
*/
-#ifdef CONFIG_FSL_ERRATUM_A008585
+#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
struct arch_timer_erratum_workaround *erratum_workaround = NULL;
DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
+#endif
-
+#ifdef CONFIG_FSL_ERRATUM_A008585
static u32 fsl_a008585_read_cntp_tval_el0(void)
{
return __fsl_a008585_read_reg(cntp_tval_el0);
@@ -139,6 +140,45 @@ static int __init early_fsl_a008585_cfg(char *buf)
early_param("clocksource.arm_arch_timer.fsl-a008585", early_fsl_a008585_cfg);
#endif /* CONFIG_FSL_ERRATUM_A008585 */
+#ifdef CONFIG_HISILICON_ERRATUM_161601
+static u32 hisi_161601_read_cntp_tval_el0(void)
+{
+ return __hisi_161601_read_reg(cntp_tval_el0);
+}
+
+static u32 hisi_161601_read_cntv_tval_el0(void)
+{
+ return __hisi_161601_read_reg(cntv_tval_el0);
+}
+
+static u64 hisi_161601_read_cntvct_el0(void)
+{
+ return __hisi_161601_read_reg(cntvct_el0);
+}
+
+static struct arch_timer_erratum_workaround arch_timer_hisi_161601 = {
+ .read_cntp_tval_el0 = hisi_161601_read_cntp_tval_el0,
+ .read_cntv_tval_el0 = hisi_161601_read_cntv_tval_el0,
+ .read_cntvct_el0 = hisi_161601_read_cntvct_el0,
+};
+
+static int __init early_hisi_161601_cfg(char *buf)
+{
+ int ret;
+ bool val;
+
+ ret = strtobool(buf, &val);
+ if (ret)
+ return ret;
+
+ if (val)
+ erratum_workaround = &arch_timer_hisi_161601;
+
+ return 0;
+}
+early_param("clocksource.arm_arch_timer.hisilicon-161601", early_hisi_161601_cfg);
+#endif /* CONFIG_HISILICON_ERRATUM_161601 */
+
static __always_inline
void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val,
struct clock_event_device *clk)
@@ -288,8 +328,8 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
}
-#ifdef CONFIG_FSL_ERRATUM_A008585
-static __always_inline void fsl_a008585_set_next_event(const int access,
+#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
+static __always_inline void erratum_set_next_event(const int access,
unsigned long evt, struct clock_event_device *clk)
{
unsigned long ctrl;
@@ -307,20 +347,20 @@ static __always_inline void fsl_a008585_set_next_event(const int access,
arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
}
-static int fsl_a008585_set_next_event_virt(unsigned long evt,
+static int erratum_set_next_event_virt(unsigned long evt,
struct clock_event_device *clk)
{
- fsl_a008585_set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk);
+ erratum_set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk);
return 0;
}
-static int fsl_a008585_set_next_event_phys(unsigned long evt,
+static int erratum_set_next_event_phys(unsigned long evt,
struct clock_event_device *clk)
{
- fsl_a008585_set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk);
+ erratum_set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk);
return 0;
}
-#endif /* CONFIG_FSL_ERRATUM_A008585 */
+#endif
static int arch_timer_set_next_event_virt(unsigned long evt,
struct clock_event_device *clk)
@@ -350,16 +390,16 @@ static int arch_timer_set_next_event_phys_mem(unsigned long evt,
return 0;
}
-static void fsl_a008585_set_sne(struct clock_event_device *clk)
+static void erratum_set_sne(struct clock_event_device *clk)
{
-#ifdef CONFIG_FSL_ERRATUM_A008585
+#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
if (!static_branch_unlikely(&arch_timer_read_ool_enabled))
return;
if (arch_timer_uses_ppi == VIRT_PPI)
- clk->set_next_event = fsl_a008585_set_next_event_virt;
+ clk->set_next_event = erratum_set_next_event_virt;
else
- clk->set_next_event = fsl_a008585_set_next_event_phys;
+ clk->set_next_event = erratum_set_next_event_phys;
#endif
}
@@ -392,7 +432,7 @@ static void __arch_timer_setup(unsigned type,
BUG();
}
- fsl_a008585_set_sne(clk);
+ erratum_set_sne(clk);
} else {
clk->features |= CLOCK_EVT_FEAT_DYNIRQ;
clk->name = "arch_mem_timer";
@@ -612,7 +652,7 @@ static void __init arch_counter_register(unsigned type)
clocksource_counter.archdata.vdso_direct = true;
-#ifdef CONFIG_FSL_ERRATUM_A008585
+#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585) || IS_ENABLED(CONFIG_HISILICON_ERRATUM_161601)
/*
* Don't use the vdso fastpath if errata require using
* the out-of-line counter accessor.
@@ -899,12 +939,22 @@ static int __init arch_timer_of_init(struct device_node *np)
arch_timer_c3stop = !of_property_read_bool(np, "always-on");
#ifdef CONFIG_FSL_ERRATUM_A008585
- if (!erratum_workaround && of_property_read_bool(np, "fsl,erratum-a008585"))
+ if (!erratum_workaround && of_property_read_bool(np, "fsl,erratum-a008585")) {
erratum_workaround = &arch_timer_fsl_a008585;
+ if (erratum_workaround) {
+ static_branch_enable(&arch_timer_read_ool_enabled);
+ pr_info("Enabling workaround for FSL erratum A-008585\n");
+ }
+ }
+#endif
- if (erratum_workaround) {
- static_branch_enable(&arch_timer_read_ool_enabled);
- pr_info("Enabling workaround for FSL erratum A-008585\n");
+#ifdef CONFIG_HISILICON_ERRATUM_161601
+ if (!erratum_workaround && of_property_read_bool(np, "hisilicon,erratum-161601")) {
+ erratum_workaround = &arch_timer_hisi_161601;
+ if (erratum_workaround) {
+ static_branch_enable(&arch_timer_read_ool_enabled);
+ pr_info("Enabling workaround for HISILICON erratum 161601\n");
+ }
}
#endif
--
1.9.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 4/4] arm64: arch timer: Add timer erratum property for Hip05-d02 and Hip06-d03
From: Ding Tianhong @ 2016-10-27 7:34 UTC (permalink / raw)
To: catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
marc.zyngier-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
oss-fOR+EgIDQEHk1uMJSBkQmQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
shawnguo-DgEjT+Ai2ygdnm+yROfE0A, stuart.yoder-3arQi8VN3Tc,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linuxarm-hv44wF8Li93QT0dZR+AlfA
Cc: Ding Tianhong
In-Reply-To: <1477553651-13428-1-git-send-email-dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Enable workaround for hisilicon erratum 161601 on Hip05-d02 and Hip06-d03 board.
Signed-off-by: Ding Tianhong <dingtianhong-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
---
arch/arm64/boot/dts/hisilicon/hip05.dtsi | 1 +
arch/arm64/boot/dts/hisilicon/hip06.dtsi | 1 +
2 files changed, 2 insertions(+)
diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
index bf322ed..f815d94 100644
--- a/arch/arm64/boot/dts/hisilicon/hip05.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
@@ -281,6 +281,7 @@
<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ hisilicon,erratum-161601;
};
pmu {
diff --git a/arch/arm64/boot/dts/hisilicon/hip06.dtsi b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
index 5927bc4..d63990b 100644
--- a/arch/arm64/boot/dts/hisilicon/hip06.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
@@ -260,6 +260,7 @@
<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ hisilicon,erratum-161601;
};
pmu {
--
1.9.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v2 5/7] [media] ir-lirc-codec: don't wait any transmitting time for tx only devices
From: Andi Shyti @ 2016-10-27 7:44 UTC (permalink / raw)
To: Sean Young
Cc: Mauro Carvalho Chehab, Rob Herring, Mark Rutland,
linux-media-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Andi Shyti,
David Härdeman
In-Reply-To: <20160902084158.GA25342-3XSxi2G4b3iXFJAUJl40Xg@public.gmane.org>
Hi Sean,
it's been a while :)
I was going through your review fixing what needs to be fixed,
but...
> > @@ -153,7 +153,7 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
> > }
> >
> > ret = dev->tx_ir(dev, txbuf, count);
> > - if (ret < 0)
> > + if (ret < 0 || dev->driver_type == RC_DRIVER_IR_RAW_TX)
>
> Just because a driver only does transmit doesn't mean its transmit ABI
> should change.
>
> Now this bit of code is pretty horrible. It ensures that the call to write()
> takes at least as long as the length of the transmit IR by sleeping. That's
> not much of a guarantee that the IR has been sent.
>
> Note that in the case of ir-spi, since your spi transfer is sync no sleep
> should be introduced here.
>
> The gap calculation in lirc checks that if the call to write() took _longer_
> than expected wait before sending the next IR code (when either multiple
> IR codes or repeats are specified). Introducing the sleep in the kernel
> here does not help at all, lirc already ensures that it waits as long as
> the IR is long (see schedule_repeat_timer in lirc).
>
> This change was introduced in 3.10, commit f8e00d5.
... I'm not sure what can be done here. I get your point and I
understand that this indeed is a kind of fake sync point and by
doing this I
How about creating two different functions:
- ir_lirc_transmit_ir where we actually do what the function
already does
- ir_lirc_transmit_no_sync where the function we don't wait
because the the sync is done on a different level (for example
in the SPI case).
SPI does approximately the same thing.
Andi
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v6 1/2] MMC: meson: initial support for GX platforms
From: Ulf Hansson @ 2016-10-27 7:47 UTC (permalink / raw)
To: Kevin Hilman
Cc: devicetree@vger.kernel.org, Rob Herring, linux-mmc,
linux-arm-kernel@lists.infradead.org, linux-amlogic
In-Reply-To: <20161019181825.2186-1-khilman@baylibre.com>
On 19 October 2016 at 20:18, Kevin Hilman <khilman@baylibre.com> wrote:
> Initial support for the SD/eMMC controller in the Amlogic S905/GX*
> family of SoCs.
>
> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
Thanks, applied for next!
Kind regards
Uffe
> ---
> Changes since v5:
> - dropped MODULE_ALIAS
> - renmaed file to meson-gx-mmc (for more useful module name)
> - update DRIVER_NAME: s/gxbb/gx/
>
> MAINTAINERS | 1 +
> drivers/mmc/host/Kconfig | 10 +
> drivers/mmc/host/Makefile | 1 +
> drivers/mmc/host/meson-gx-mmc.c | 852 ++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 864 insertions(+)
> create mode 100644 drivers/mmc/host/meson-gx-mmc.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 1cd38a7e0064..73e8d64ec28c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1036,6 +1036,7 @@ F: arch/arm/mach-meson/
> F: arch/arm/boot/dts/meson*
> F: arch/arm64/boot/dts/amlogic/
> F: drivers/pinctrl/meson/
> +F: drivers/mmc/host/meson*
> N: meson
>
> ARM/Annapurna Labs ALPINE ARCHITECTURE
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 5274f503a39a..5cf7ebaf1e8b 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -322,6 +322,16 @@ config MMC_SDHCI_IPROC
>
> If unsure, say N.
>
> +config MMC_MESON_GX
> + tristate "Amlogic S905/GX* SD/MMC Host Controller support"
> + depends on ARCH_MESON && MMC
> + help
> + This selects support for the Amlogic SD/MMC Host Controller
> + found on the S905/GX* family of SoCs. This controller is
> + MMC 5.1 compliant and supports SD, eMMC and SDIO interfaces.
> +
> + If you have a controller with this interface, say Y here.
> +
> config MMC_MOXART
> tristate "MOXART SD/MMC Host Controller support"
> depends on ARCH_MOXART && MMC
> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> index e2bdaaf43184..e609bf04346b 100644
> --- a/drivers/mmc/host/Makefile
> +++ b/drivers/mmc/host/Makefile
> @@ -53,6 +53,7 @@ obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o
> obj-$(CONFIG_MMC_VUB300) += vub300.o
> obj-$(CONFIG_MMC_USHC) += ushc.o
> obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o
> +obj-$(CONFIG_MMC_MESON_GX) += meson-gx-mmc.o
> obj-$(CONFIG_MMC_MOXART) += moxart-mmc.o
> obj-$(CONFIG_MMC_SUNXI) += sunxi-mmc.o
> obj-$(CONFIG_MMC_USDHI6ROL0) += usdhi6rol0.o
> diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
> new file mode 100644
> index 000000000000..1fcab7116f26
> --- /dev/null
> +++ b/drivers/mmc/host/meson-gx-mmc.c
> @@ -0,0 +1,852 @@
> +/*
> + * Amlogic SD/eMMC driver for the GX/S905 family SoCs
> + *
> + * Copyright (c) 2016 BayLibre, SAS.
> + * Author: Kevin Hilman <khilman@baylibre.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of version 2 of the GNU General Public License as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, see <http://www.gnu.org/licenses/>.
> + * The full GNU General Public License is included in this distribution
> + * in the file called COPYING.
> + */
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/device.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/ioport.h>
> +#include <linux/spinlock.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/mmc/host.h>
> +#include <linux/mmc/mmc.h>
> +#include <linux/mmc/sdio.h>
> +#include <linux/mmc/slot-gpio.h>
> +#include <linux/io.h>
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/regulator/consumer.h>
> +
> +#define DRIVER_NAME "meson-gx-mmc"
> +
> +#define SD_EMMC_CLOCK 0x0
> +#define CLK_DIV_SHIFT 0
> +#define CLK_DIV_WIDTH 6
> +#define CLK_DIV_MASK 0x3f
> +#define CLK_DIV_MAX 63
> +#define CLK_SRC_SHIFT 6
> +#define CLK_SRC_WIDTH 2
> +#define CLK_SRC_MASK 0x3
> +#define CLK_SRC_XTAL 0 /* external crystal */
> +#define CLK_SRC_XTAL_RATE 24000000
> +#define CLK_SRC_PLL 1 /* FCLK_DIV2 */
> +#define CLK_SRC_PLL_RATE 1000000000
> +#define CLK_PHASE_SHIFT 8
> +#define CLK_PHASE_MASK 0x3
> +#define CLK_PHASE_0 0
> +#define CLK_PHASE_90 1
> +#define CLK_PHASE_180 2
> +#define CLK_PHASE_270 3
> +#define CLK_ALWAYS_ON BIT(24)
> +
> +#define SD_EMMC_DElAY 0x4
> +#define SD_EMMC_ADJUST 0x8
> +#define SD_EMMC_CALOUT 0x10
> +#define SD_EMMC_START 0x40
> +#define START_DESC_INIT BIT(0)
> +#define START_DESC_BUSY BIT(1)
> +#define START_DESC_ADDR_SHIFT 2
> +#define START_DESC_ADDR_MASK (~0x3)
> +
> +#define SD_EMMC_CFG 0x44
> +#define CFG_BUS_WIDTH_SHIFT 0
> +#define CFG_BUS_WIDTH_MASK 0x3
> +#define CFG_BUS_WIDTH_1 0x0
> +#define CFG_BUS_WIDTH_4 0x1
> +#define CFG_BUS_WIDTH_8 0x2
> +#define CFG_DDR BIT(2)
> +#define CFG_BLK_LEN_SHIFT 4
> +#define CFG_BLK_LEN_MASK 0xf
> +#define CFG_RESP_TIMEOUT_SHIFT 8
> +#define CFG_RESP_TIMEOUT_MASK 0xf
> +#define CFG_RC_CC_SHIFT 12
> +#define CFG_RC_CC_MASK 0xf
> +#define CFG_STOP_CLOCK BIT(22)
> +#define CFG_CLK_ALWAYS_ON BIT(18)
> +#define CFG_AUTO_CLK BIT(23)
> +
> +#define SD_EMMC_STATUS 0x48
> +#define STATUS_BUSY BIT(31)
> +
> +#define SD_EMMC_IRQ_EN 0x4c
> +#define IRQ_EN_MASK 0x3fff
> +#define IRQ_RXD_ERR_SHIFT 0
> +#define IRQ_RXD_ERR_MASK 0xff
> +#define IRQ_TXD_ERR BIT(8)
> +#define IRQ_DESC_ERR BIT(9)
> +#define IRQ_RESP_ERR BIT(10)
> +#define IRQ_RESP_TIMEOUT BIT(11)
> +#define IRQ_DESC_TIMEOUT BIT(12)
> +#define IRQ_END_OF_CHAIN BIT(13)
> +#define IRQ_RESP_STATUS BIT(14)
> +#define IRQ_SDIO BIT(15)
> +
> +#define SD_EMMC_CMD_CFG 0x50
> +#define SD_EMMC_CMD_ARG 0x54
> +#define SD_EMMC_CMD_DAT 0x58
> +#define SD_EMMC_CMD_RSP 0x5c
> +#define SD_EMMC_CMD_RSP1 0x60
> +#define SD_EMMC_CMD_RSP2 0x64
> +#define SD_EMMC_CMD_RSP3 0x68
> +
> +#define SD_EMMC_RXD 0x94
> +#define SD_EMMC_TXD 0x94
> +#define SD_EMMC_LAST_REG SD_EMMC_TXD
> +
> +#define SD_EMMC_CFG_BLK_SIZE 512 /* internal buffer max: 512 bytes */
> +#define SD_EMMC_CFG_RESP_TIMEOUT 256 /* in clock cycles */
> +#define SD_EMMC_CFG_CMD_GAP 16 /* in clock cycles */
> +#define MUX_CLK_NUM_PARENTS 2
> +
> +struct meson_host {
> + struct device *dev;
> + struct mmc_host *mmc;
> + struct mmc_request *mrq;
> + struct mmc_command *cmd;
> +
> + spinlock_t lock;
> + void __iomem *regs;
> + int irq;
> + u32 ocr_mask;
> + struct clk *core_clk;
> + struct clk_mux mux;
> + struct clk *mux_clk;
> + struct clk *mux_parent[MUX_CLK_NUM_PARENTS];
> + unsigned long mux_parent_rate[MUX_CLK_NUM_PARENTS];
> +
> + struct clk_divider cfg_div;
> + struct clk *cfg_div_clk;
> +
> + unsigned int bounce_buf_size;
> + void *bounce_buf;
> + dma_addr_t bounce_dma_addr;
> +
> + bool vqmmc_enabled;
> +};
> +
> +struct sd_emmc_desc {
> + u32 cmd_cfg;
> + u32 cmd_arg;
> + u32 cmd_data;
> + u32 cmd_resp;
> +};
> +#define CMD_CFG_LENGTH_SHIFT 0
> +#define CMD_CFG_LENGTH_MASK 0x1ff
> +#define CMD_CFG_BLOCK_MODE BIT(9)
> +#define CMD_CFG_R1B BIT(10)
> +#define CMD_CFG_END_OF_CHAIN BIT(11)
> +#define CMD_CFG_TIMEOUT_SHIFT 12
> +#define CMD_CFG_TIMEOUT_MASK 0xf
> +#define CMD_CFG_NO_RESP BIT(16)
> +#define CMD_CFG_NO_CMD BIT(17)
> +#define CMD_CFG_DATA_IO BIT(18)
> +#define CMD_CFG_DATA_WR BIT(19)
> +#define CMD_CFG_RESP_NOCRC BIT(20)
> +#define CMD_CFG_RESP_128 BIT(21)
> +#define CMD_CFG_RESP_NUM BIT(22)
> +#define CMD_CFG_DATA_NUM BIT(23)
> +#define CMD_CFG_CMD_INDEX_SHIFT 24
> +#define CMD_CFG_CMD_INDEX_MASK 0x3f
> +#define CMD_CFG_ERROR BIT(30)
> +#define CMD_CFG_OWNER BIT(31)
> +
> +#define CMD_DATA_MASK (~0x3)
> +#define CMD_DATA_BIG_ENDIAN BIT(1)
> +#define CMD_DATA_SRAM BIT(0)
> +#define CMD_RESP_MASK (~0x1)
> +#define CMD_RESP_SRAM BIT(0)
> +
> +static int meson_mmc_clk_set(struct meson_host *host, unsigned long clk_rate)
> +{
> + struct mmc_host *mmc = host->mmc;
> + int ret = 0;
> + u32 cfg;
> +
> + if (clk_rate) {
> + if (WARN_ON(clk_rate > mmc->f_max))
> + clk_rate = mmc->f_max;
> + else if (WARN_ON(clk_rate < mmc->f_min))
> + clk_rate = mmc->f_min;
> + }
> +
> + if (clk_rate == mmc->actual_clock)
> + return 0;
> +
> + /* stop clock */
> + cfg = readl(host->regs + SD_EMMC_CFG);
> + if (!(cfg & CFG_STOP_CLOCK)) {
> + cfg |= CFG_STOP_CLOCK;
> + writel(cfg, host->regs + SD_EMMC_CFG);
> + }
> +
> + dev_dbg(host->dev, "change clock rate %u -> %lu\n",
> + mmc->actual_clock, clk_rate);
> +
> + if (clk_rate == 0) {
> + mmc->actual_clock = 0;
> + return 0;
> + }
> +
> + ret = clk_set_rate(host->cfg_div_clk, clk_rate);
> + if (ret)
> + dev_warn(host->dev, "Unable to set cfg_div_clk to %lu. ret=%d\n",
> + clk_rate, ret);
> + else if (clk_rate && clk_rate != clk_get_rate(host->cfg_div_clk))
> + dev_warn(host->dev, "divider requested rate %lu != actual rate %lu: ret=%d\n",
> + clk_rate, clk_get_rate(host->cfg_div_clk), ret);
> + else
> + mmc->actual_clock = clk_rate;
> +
> + /* (re)start clock, if non-zero */
> + if (!ret && clk_rate) {
> + cfg = readl(host->regs + SD_EMMC_CFG);
> + cfg &= ~CFG_STOP_CLOCK;
> + writel(cfg, host->regs + SD_EMMC_CFG);
> + }
> +
> + return ret;
> +}
> +
> +/*
> + * The SD/eMMC IP block has an internal mux and divider used for
> + * generating the MMC clock. Use the clock framework to create and
> + * manage these clocks.
> + */
> +static int meson_mmc_clk_init(struct meson_host *host)
> +{
> + struct clk_init_data init;
> + char clk_name[32];
> + int i, ret = 0;
> + const char *mux_parent_names[MUX_CLK_NUM_PARENTS];
> + unsigned int mux_parent_count = 0;
> + const char *clk_div_parents[1];
> + unsigned int f_min = UINT_MAX;
> + u32 clk_reg, cfg;
> +
> + /* get the mux parents */
> + for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
> + char name[16];
> +
> + snprintf(name, sizeof(name), "clkin%d", i);
> + host->mux_parent[i] = devm_clk_get(host->dev, name);
> + if (IS_ERR(host->mux_parent[i])) {
> + ret = PTR_ERR(host->mux_parent[i]);
> + if (PTR_ERR(host->mux_parent[i]) != -EPROBE_DEFER)
> + dev_err(host->dev, "Missing clock %s\n", name);
> + host->mux_parent[i] = NULL;
> + return ret;
> + }
> +
> + host->mux_parent_rate[i] = clk_get_rate(host->mux_parent[i]);
> + mux_parent_names[i] = __clk_get_name(host->mux_parent[i]);
> + mux_parent_count++;
> + if (host->mux_parent_rate[i] < f_min)
> + f_min = host->mux_parent_rate[i];
> + }
> +
> + /* cacluate f_min based on input clocks, and max divider value */
> + if (f_min != UINT_MAX)
> + f_min = DIV_ROUND_UP(CLK_SRC_XTAL_RATE, CLK_DIV_MAX);
> + else
> + f_min = 4000000; /* default min: 400 MHz */
> + host->mmc->f_min = f_min;
> +
> + /* create the mux */
> + snprintf(clk_name, sizeof(clk_name), "%s#mux", dev_name(host->dev));
> + init.name = clk_name;
> + init.ops = &clk_mux_ops;
> + init.flags = 0;
> + init.parent_names = mux_parent_names;
> + init.num_parents = mux_parent_count;
> +
> + host->mux.reg = host->regs + SD_EMMC_CLOCK;
> + host->mux.shift = CLK_SRC_SHIFT;
> + host->mux.mask = CLK_SRC_MASK;
> + host->mux.flags = 0;
> + host->mux.table = NULL;
> + host->mux.hw.init = &init;
> +
> + host->mux_clk = devm_clk_register(host->dev, &host->mux.hw);
> + if (WARN_ON(IS_ERR(host->mux_clk)))
> + return PTR_ERR(host->mux_clk);
> +
> + /* create the divider */
> + snprintf(clk_name, sizeof(clk_name), "%s#div", dev_name(host->dev));
> + init.name = devm_kstrdup(host->dev, clk_name, GFP_KERNEL);
> + init.ops = &clk_divider_ops;
> + init.flags = CLK_SET_RATE_PARENT;
> + clk_div_parents[0] = __clk_get_name(host->mux_clk);
> + init.parent_names = clk_div_parents;
> + init.num_parents = ARRAY_SIZE(clk_div_parents);
> +
> + host->cfg_div.reg = host->regs + SD_EMMC_CLOCK;
> + host->cfg_div.shift = CLK_DIV_SHIFT;
> + host->cfg_div.width = CLK_DIV_WIDTH;
> + host->cfg_div.hw.init = &init;
> + host->cfg_div.flags = CLK_DIVIDER_ONE_BASED |
> + CLK_DIVIDER_ROUND_CLOSEST | CLK_DIVIDER_ALLOW_ZERO;
> +
> + host->cfg_div_clk = devm_clk_register(host->dev, &host->cfg_div.hw);
> + if (WARN_ON(PTR_ERR_OR_ZERO(host->cfg_div_clk)))
> + return PTR_ERR(host->cfg_div_clk);
> +
> + /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
> + clk_reg = 0;
> + clk_reg |= CLK_PHASE_180 << CLK_PHASE_SHIFT;
> + clk_reg |= CLK_SRC_XTAL << CLK_SRC_SHIFT;
> + clk_reg |= CLK_DIV_MAX << CLK_DIV_SHIFT;
> + clk_reg &= ~CLK_ALWAYS_ON;
> + writel(clk_reg, host->regs + SD_EMMC_CLOCK);
> +
> + /* Ensure clock starts in "auto" mode, not "always on" */
> + cfg = readl(host->regs + SD_EMMC_CFG);
> + cfg &= ~CFG_CLK_ALWAYS_ON;
> + cfg |= CFG_AUTO_CLK;
> + writel(cfg, host->regs + SD_EMMC_CFG);
> +
> + ret = clk_prepare_enable(host->cfg_div_clk);
> + if (!ret)
> + ret = meson_mmc_clk_set(host, f_min);
> +
> + if (!ret)
> + clk_disable_unprepare(host->cfg_div_clk);
> +
> + return ret;
> +}
> +
> +static void meson_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> +{
> + struct meson_host *host = mmc_priv(mmc);
> + u32 bus_width;
> + u32 val, orig;
> +
> + /*
> + * GPIO regulator, only controls switching between 1v8 and
> + * 3v3, doesn't support MMC_POWER_OFF, MMC_POWER_ON.
> + */
> + switch (ios->power_mode) {
> + case MMC_POWER_OFF:
> + if (!IS_ERR(mmc->supply.vmmc))
> + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
> +
> + if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) {
> + regulator_disable(mmc->supply.vqmmc);
> + host->vqmmc_enabled = false;
> + }
> +
> + break;
> +
> + case MMC_POWER_UP:
> + if (!IS_ERR(mmc->supply.vmmc))
> + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);
> + break;
> +
> + case MMC_POWER_ON:
> + if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) {
> + int ret = regulator_enable(mmc->supply.vqmmc);
> +
> + if (ret < 0)
> + dev_err(mmc_dev(mmc),
> + "failed to enable vqmmc regulator\n");
> + else
> + host->vqmmc_enabled = true;
> + }
> +
> + break;
> + }
> +
> +
> + meson_mmc_clk_set(host, ios->clock);
> +
> + /* Bus width */
> + val = readl(host->regs + SD_EMMC_CFG);
> + switch (ios->bus_width) {
> + case MMC_BUS_WIDTH_1:
> + bus_width = CFG_BUS_WIDTH_1;
> + break;
> + case MMC_BUS_WIDTH_4:
> + bus_width = CFG_BUS_WIDTH_4;
> + break;
> + case MMC_BUS_WIDTH_8:
> + bus_width = CFG_BUS_WIDTH_8;
> + break;
> + default:
> + dev_err(host->dev, "Invalid ios->bus_width: %u. Setting to 4.\n",
> + ios->bus_width);
> + bus_width = CFG_BUS_WIDTH_4;
> + return;
> + }
> +
> + val = readl(host->regs + SD_EMMC_CFG);
> + orig = val;
> +
> + val &= ~(CFG_BUS_WIDTH_MASK << CFG_BUS_WIDTH_SHIFT);
> + val |= bus_width << CFG_BUS_WIDTH_SHIFT;
> +
> + val &= ~(CFG_BLK_LEN_MASK << CFG_BLK_LEN_SHIFT);
> + val |= ilog2(SD_EMMC_CFG_BLK_SIZE) << CFG_BLK_LEN_SHIFT;
> +
> + val &= ~(CFG_RESP_TIMEOUT_MASK << CFG_RESP_TIMEOUT_SHIFT);
> + val |= ilog2(SD_EMMC_CFG_RESP_TIMEOUT) << CFG_RESP_TIMEOUT_SHIFT;
> +
> + val &= ~(CFG_RC_CC_MASK << CFG_RC_CC_SHIFT);
> + val |= ilog2(SD_EMMC_CFG_CMD_GAP) << CFG_RC_CC_SHIFT;
> +
> + writel(val, host->regs + SD_EMMC_CFG);
> +
> + if (val != orig)
> + dev_dbg(host->dev, "%s: SD_EMMC_CFG: 0x%08x -> 0x%08x\n",
> + __func__, orig, val);
> +}
> +
> +static int meson_mmc_request_done(struct mmc_host *mmc, struct mmc_request *mrq)
> +{
> + struct meson_host *host = mmc_priv(mmc);
> +
> + WARN_ON(host->mrq != mrq);
> +
> + host->mrq = NULL;
> + host->cmd = NULL;
> + mmc_request_done(host->mmc, mrq);
> +
> + return 0;
> +}
> +
> +static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd)
> +{
> + struct meson_host *host = mmc_priv(mmc);
> + struct sd_emmc_desc *desc, desc_tmp;
> + u32 cfg;
> + u8 blk_len, cmd_cfg_timeout;
> + unsigned int xfer_bytes = 0;
> +
> + /* Setup descriptors */
> + dma_rmb();
> + desc = &desc_tmp;
> + memset(desc, 0, sizeof(struct sd_emmc_desc));
> +
> + desc->cmd_cfg |= (cmd->opcode & CMD_CFG_CMD_INDEX_MASK) <<
> + CMD_CFG_CMD_INDEX_SHIFT;
> + desc->cmd_cfg |= CMD_CFG_OWNER; /* owned by CPU */
> + desc->cmd_arg = cmd->arg;
> +
> + /* Response */
> + if (cmd->flags & MMC_RSP_PRESENT) {
> + desc->cmd_cfg &= ~CMD_CFG_NO_RESP;
> + if (cmd->flags & MMC_RSP_136)
> + desc->cmd_cfg |= CMD_CFG_RESP_128;
> + desc->cmd_cfg |= CMD_CFG_RESP_NUM;
> + desc->cmd_resp = 0;
> +
> + if (!(cmd->flags & MMC_RSP_CRC))
> + desc->cmd_cfg |= CMD_CFG_RESP_NOCRC;
> +
> + if (cmd->flags & MMC_RSP_BUSY)
> + desc->cmd_cfg |= CMD_CFG_R1B;
> + } else {
> + desc->cmd_cfg |= CMD_CFG_NO_RESP;
> + }
> +
> + /* data? */
> + if (cmd->data) {
> + desc->cmd_cfg |= CMD_CFG_DATA_IO;
> + if (cmd->data->blocks > 1) {
> + desc->cmd_cfg |= CMD_CFG_BLOCK_MODE;
> + desc->cmd_cfg |=
> + (cmd->data->blocks & CMD_CFG_LENGTH_MASK) <<
> + CMD_CFG_LENGTH_SHIFT;
> +
> + /* check if block-size matches, if not update */
> + cfg = readl(host->regs + SD_EMMC_CFG);
> + blk_len = cfg & (CFG_BLK_LEN_MASK << CFG_BLK_LEN_SHIFT);
> + blk_len >>= CFG_BLK_LEN_SHIFT;
> + if (blk_len != ilog2(cmd->data->blksz)) {
> + dev_warn(host->dev, "%s: update blk_len %d -> %d\n",
> + __func__, blk_len,
> + ilog2(cmd->data->blksz));
> + blk_len = ilog2(cmd->data->blksz);
> + cfg &= ~(CFG_BLK_LEN_MASK << CFG_BLK_LEN_SHIFT);
> + cfg |= blk_len << CFG_BLK_LEN_SHIFT;
> + writel(cfg, host->regs + SD_EMMC_CFG);
> + }
> + } else {
> + desc->cmd_cfg &= ~CMD_CFG_BLOCK_MODE;
> + desc->cmd_cfg |=
> + (cmd->data->blksz & CMD_CFG_LENGTH_MASK) <<
> + CMD_CFG_LENGTH_SHIFT;
> + }
> +
> + cmd->data->bytes_xfered = 0;
> + xfer_bytes = cmd->data->blksz * cmd->data->blocks;
> + if (cmd->data->flags & MMC_DATA_WRITE) {
> + desc->cmd_cfg |= CMD_CFG_DATA_WR;
> + WARN_ON(xfer_bytes > host->bounce_buf_size);
> + sg_copy_to_buffer(cmd->data->sg, cmd->data->sg_len,
> + host->bounce_buf, xfer_bytes);
> + cmd->data->bytes_xfered = xfer_bytes;
> + dma_wmb();
> + } else {
> + desc->cmd_cfg &= ~CMD_CFG_DATA_WR;
> + }
> +
> + if (xfer_bytes > 0) {
> + desc->cmd_cfg &= ~CMD_CFG_DATA_NUM;
> + desc->cmd_data = host->bounce_dma_addr & CMD_DATA_MASK;
> + } else {
> + /* write data to data_addr */
> + desc->cmd_cfg |= CMD_CFG_DATA_NUM;
> + desc->cmd_data = 0;
> + }
> +
> + cmd_cfg_timeout = 12;
> + } else {
> + desc->cmd_cfg &= ~CMD_CFG_DATA_IO;
> + cmd_cfg_timeout = 10;
> + }
> + desc->cmd_cfg |= (cmd_cfg_timeout & CMD_CFG_TIMEOUT_MASK) <<
> + CMD_CFG_TIMEOUT_SHIFT;
> +
> + host->cmd = cmd;
> +
> + /* Last descriptor */
> + desc->cmd_cfg |= CMD_CFG_END_OF_CHAIN;
> + writel(desc->cmd_cfg, host->regs + SD_EMMC_CMD_CFG);
> + writel(desc->cmd_data, host->regs + SD_EMMC_CMD_DAT);
> + writel(desc->cmd_resp, host->regs + SD_EMMC_CMD_RSP);
> + wmb(); /* ensure descriptor is written before kicked */
> + writel(desc->cmd_arg, host->regs + SD_EMMC_CMD_ARG);
> +}
> +
> +static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
> +{
> + struct meson_host *host = mmc_priv(mmc);
> +
> + WARN_ON(host->mrq != NULL);
> +
> + /* Stop execution */
> + writel(0, host->regs + SD_EMMC_START);
> +
> + /* clear, ack, enable all interrupts */
> + writel(0, host->regs + SD_EMMC_IRQ_EN);
> + writel(IRQ_EN_MASK, host->regs + SD_EMMC_STATUS);
> + writel(IRQ_EN_MASK, host->regs + SD_EMMC_IRQ_EN);
> +
> + host->mrq = mrq;
> +
> + if (mrq->sbc)
> + meson_mmc_start_cmd(mmc, mrq->sbc);
> + else
> + meson_mmc_start_cmd(mmc, mrq->cmd);
> +}
> +
> +static int meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd)
> +{
> + struct meson_host *host = mmc_priv(mmc);
> +
> + if (cmd->flags & MMC_RSP_136) {
> + cmd->resp[0] = readl(host->regs + SD_EMMC_CMD_RSP3);
> + cmd->resp[1] = readl(host->regs + SD_EMMC_CMD_RSP2);
> + cmd->resp[2] = readl(host->regs + SD_EMMC_CMD_RSP1);
> + cmd->resp[3] = readl(host->regs + SD_EMMC_CMD_RSP);
> + } else if (cmd->flags & MMC_RSP_PRESENT) {
> + cmd->resp[0] = readl(host->regs + SD_EMMC_CMD_RSP);
> + }
> +
> + return 0;
> +}
> +
> +static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
> +{
> + struct meson_host *host = dev_id;
> + struct mmc_request *mrq;
> + struct mmc_command *cmd = host->cmd;
> + u32 irq_en, status, raw_status;
> + irqreturn_t ret = IRQ_HANDLED;
> +
> + if (WARN_ON(!host))
> + return IRQ_NONE;
> +
> + mrq = host->mrq;
> +
> + if (WARN_ON(!mrq))
> + return IRQ_NONE;
> +
> + if (WARN_ON(!cmd))
> + return IRQ_NONE;
> +
> + spin_lock(&host->lock);
> + irq_en = readl(host->regs + SD_EMMC_IRQ_EN);
> + raw_status = readl(host->regs + SD_EMMC_STATUS);
> + status = raw_status & irq_en;
> +
> + if (!status) {
> + dev_warn(host->dev, "Spurious IRQ! status=0x%08x, irq_en=0x%08x\n",
> + raw_status, irq_en);
> + ret = IRQ_NONE;
> + goto out;
> + }
> +
> + cmd->error = 0;
> + if (status & IRQ_RXD_ERR_MASK) {
> + dev_dbg(host->dev, "Unhandled IRQ: RXD error\n");
> + cmd->error = -EILSEQ;
> + }
> + if (status & IRQ_TXD_ERR) {
> + dev_dbg(host->dev, "Unhandled IRQ: TXD error\n");
> + cmd->error = -EILSEQ;
> + }
> + if (status & IRQ_DESC_ERR)
> + dev_dbg(host->dev, "Unhandled IRQ: Descriptor error\n");
> + if (status & IRQ_RESP_ERR) {
> + dev_dbg(host->dev, "Unhandled IRQ: Response error\n");
> + cmd->error = -EILSEQ;
> + }
> + if (status & IRQ_RESP_TIMEOUT) {
> + dev_dbg(host->dev, "Unhandled IRQ: Response timeout\n");
> + cmd->error = -ETIMEDOUT;
> + }
> + if (status & IRQ_DESC_TIMEOUT) {
> + dev_dbg(host->dev, "Unhandled IRQ: Descriptor timeout\n");
> + cmd->error = -ETIMEDOUT;
> + }
> + if (status & IRQ_SDIO)
> + dev_dbg(host->dev, "Unhandled IRQ: SDIO.\n");
> +
> + if (status & (IRQ_END_OF_CHAIN | IRQ_RESP_STATUS))
> + ret = IRQ_WAKE_THREAD;
> + else {
> + dev_warn(host->dev, "Unknown IRQ! status=0x%04x: MMC CMD%u arg=0x%08x flags=0x%08x stop=%d\n",
> + status, cmd->opcode, cmd->arg,
> + cmd->flags, mrq->stop ? 1 : 0);
> + if (cmd->data) {
> + struct mmc_data *data = cmd->data;
> +
> + dev_warn(host->dev, "\tblksz %u blocks %u flags 0x%08x (%s%s)",
> + data->blksz, data->blocks, data->flags,
> + data->flags & MMC_DATA_WRITE ? "write" : "",
> + data->flags & MMC_DATA_READ ? "read" : "");
> + }
> + }
> +
> +out:
> + /* ack all (enabled) interrupts */
> + writel(status, host->regs + SD_EMMC_STATUS);
> +
> + if (ret == IRQ_HANDLED) {
> + meson_mmc_read_resp(host->mmc, cmd);
> + meson_mmc_request_done(host->mmc, cmd->mrq);
> + }
> +
> + spin_unlock(&host->lock);
> + return ret;
> +}
> +
> +static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
> +{
> + struct meson_host *host = dev_id;
> + struct mmc_request *mrq = host->mrq;
> + struct mmc_command *cmd = host->cmd;
> + struct mmc_data *data;
> + unsigned int xfer_bytes;
> + int ret = IRQ_HANDLED;
> +
> + if (WARN_ON(!mrq))
> + ret = IRQ_NONE;
> +
> + if (WARN_ON(!cmd))
> + ret = IRQ_NONE;
> +
> + data = cmd->data;
> + if (data) {
> + xfer_bytes = data->blksz * data->blocks;
> + if (data->flags & MMC_DATA_READ) {
> + WARN_ON(xfer_bytes > host->bounce_buf_size);
> + sg_copy_from_buffer(data->sg, data->sg_len,
> + host->bounce_buf, xfer_bytes);
> + data->bytes_xfered = xfer_bytes;
> + }
> + }
> +
> + meson_mmc_read_resp(host->mmc, cmd);
> + if (!data || !data->stop || mrq->sbc)
> + meson_mmc_request_done(host->mmc, mrq);
> + else
> + meson_mmc_start_cmd(host->mmc, data->stop);
> +
> + return ret;
> +}
> +
> +/*
> + * NOTE: we only need this until the GPIO/pinctrl driver can handle
> + * interrupts. For now, the MMC core will use this for polling.
> + */
> +static int meson_mmc_get_cd(struct mmc_host *mmc)
> +{
> + int status = mmc_gpio_get_cd(mmc);
> +
> + if (status == -ENOSYS)
> + return 1; /* assume present */
> +
> + return status;
> +}
> +
> +static const struct mmc_host_ops meson_mmc_ops = {
> + .request = meson_mmc_request,
> + .set_ios = meson_mmc_set_ios,
> + .get_cd = meson_mmc_get_cd,
> +};
> +
> +static int meson_mmc_probe(struct platform_device *pdev)
> +{
> + struct resource *res;
> + struct meson_host *host;
> + struct mmc_host *mmc;
> + int ret;
> +
> + mmc = mmc_alloc_host(sizeof(struct meson_host), &pdev->dev);
> + if (!mmc)
> + return -ENOMEM;
> + host = mmc_priv(mmc);
> + host->mmc = mmc;
> + host->dev = &pdev->dev;
> + dev_set_drvdata(&pdev->dev, host);
> +
> + spin_lock_init(&host->lock);
> +
> + /* Get regulators and the supported OCR mask */
> + host->vqmmc_enabled = false;
> + ret = mmc_regulator_get_supply(mmc);
> + if (ret == -EPROBE_DEFER)
> + goto free_host;
> +
> + ret = mmc_of_parse(mmc);
> + if (ret) {
> + dev_warn(&pdev->dev, "error parsing DT: %d\n", ret);
> + goto free_host;
> + }
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + host->regs = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(host->regs)) {
> + ret = PTR_ERR(host->regs);
> + goto free_host;
> + }
> +
> + host->irq = platform_get_irq(pdev, 0);
> + if (host->irq == 0) {
> + dev_err(&pdev->dev, "failed to get interrupt resource.\n");
> + ret = -EINVAL;
> + goto free_host;
> + }
> +
> + host->core_clk = devm_clk_get(&pdev->dev, "core");
> + if (IS_ERR(host->core_clk)) {
> + ret = PTR_ERR(host->core_clk);
> + goto free_host;
> + }
> +
> + ret = clk_prepare_enable(host->core_clk);
> + if (ret)
> + goto free_host;
> +
> + ret = meson_mmc_clk_init(host);
> + if (ret)
> + goto free_host;
> +
> + /* Stop execution */
> + writel(0, host->regs + SD_EMMC_START);
> +
> + /* clear, ack, enable all interrupts */
> + writel(0, host->regs + SD_EMMC_IRQ_EN);
> + writel(IRQ_EN_MASK, host->regs + SD_EMMC_STATUS);
> +
> + ret = devm_request_threaded_irq(&pdev->dev, host->irq,
> + meson_mmc_irq, meson_mmc_irq_thread,
> + IRQF_SHARED, DRIVER_NAME, host);
> + if (ret)
> + goto free_host;
> +
> + /* data bounce buffer */
> + host->bounce_buf_size = SZ_512K;
> + host->bounce_buf =
> + dma_alloc_coherent(host->dev, host->bounce_buf_size,
> + &host->bounce_dma_addr, GFP_KERNEL);
> + if (host->bounce_buf == NULL) {
> + dev_err(host->dev, "Unable to map allocate DMA bounce buffer.\n");
> + ret = -ENOMEM;
> + goto free_host;
> + }
> +
> + mmc->ops = &meson_mmc_ops;
> + mmc_add_host(mmc);
> +
> + return 0;
> +
> +free_host:
> + clk_disable_unprepare(host->cfg_div_clk);
> + clk_disable_unprepare(host->core_clk);
> + mmc_free_host(mmc);
> + return ret;
> +}
> +
> +static int meson_mmc_remove(struct platform_device *pdev)
> +{
> + struct meson_host *host = dev_get_drvdata(&pdev->dev);
> +
> + if (WARN_ON(!host))
> + return 0;
> +
> + if (host->bounce_buf)
> + dma_free_coherent(host->dev, host->bounce_buf_size,
> + host->bounce_buf, host->bounce_dma_addr);
> +
> + clk_disable_unprepare(host->cfg_div_clk);
> + clk_disable_unprepare(host->core_clk);
> +
> + mmc_free_host(host->mmc);
> + return 0;
> +}
> +
> +static const struct of_device_id meson_mmc_of_match[] = {
> + { .compatible = "amlogic,meson-gx-mmc", },
> + { .compatible = "amlogic,meson-gxbb-mmc", },
> + { .compatible = "amlogic,meson-gxl-mmc", },
> + { .compatible = "amlogic,meson-gxm-mmc", },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, meson_mmc_of_match);
> +
> +static struct platform_driver meson_mmc_driver = {
> + .probe = meson_mmc_probe,
> + .remove = meson_mmc_remove,
> + .driver = {
> + .name = DRIVER_NAME,
> + .of_match_table = of_match_ptr(meson_mmc_of_match),
> + },
> +};
> +
> +module_platform_driver(meson_mmc_driver);
> +
> +MODULE_DESCRIPTION("Amlogic S905*/GX* SD/eMMC driver");
> +MODULE_AUTHOR("Kevin Hilman <khilman@baylibre.com>");
> +MODULE_LICENSE("GPL v2");
> +
> --
> 2.9.3
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox