[PATCH v5 2/3] input: syscon support in bcm_iproc_tsc driver
In Cygnus SOC touch screen controller registers are shared with ADC and flex timer. Using readl/writel could lead to race condition. So touch screen driver is enhanced to support register access using syscon framework API's to take care of mutually exclusive access. Signed-off-by: Raveendra PadasalagiReviewed-by: Ray Jui Reviewed-by: Scott Branden Reviewed-by: Arnd Bergmann --- drivers/input/touchscreen/bcm_iproc_tsc.c | 79 +-- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/drivers/input/touchscreen/bcm_iproc_tsc.c b/drivers/input/touchscreen/bcm_iproc_tsc.c index ae460a5c..0fd5f35 100644 --- a/drivers/input/touchscreen/bcm_iproc_tsc.c +++ b/drivers/input/touchscreen/bcm_iproc_tsc.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #define IPROC_TS_NAME "iproc-ts" @@ -88,7 +90,11 @@ #define TS_WIRE_MODE_BITBIT(1) #define dbg_reg(dev, priv, reg) \ - dev_dbg(dev, "%20s= 0x%08x\n", #reg, readl((priv)->regs + reg)) +do { \ + u32 val; \ + regmap_read(priv->regmap, reg, ); \ + dev_dbg(dev, "%20s= 0x%08x\n", #reg, val); \ +} while (0) struct tsc_param { /* Each step is 1024 us. Valid 1-256 */ @@ -141,7 +147,7 @@ struct iproc_ts_priv { struct platform_device *pdev; struct input_dev *idev; - void __iomem *regs; + struct regmap *regmap; struct clk *tsc_clk; int pen_status; @@ -196,22 +202,22 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, void *data) int i; bool needs_sync = false; - intr_status = readl(priv->regs + INTERRUPT_STATUS); - intr_status &= TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK; + regmap_read(priv->regmap, INTERRUPT_STATUS, _status); + intr_status &= (TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK); if (intr_status == 0) return IRQ_NONE; /* Clear all interrupt status bits, write-1-clear */ - writel(intr_status, priv->regs + INTERRUPT_STATUS); - + regmap_write(priv->regmap, INTERRUPT_STATUS, intr_status); /* Pen up/down */ if (intr_status & TS_PEN_INTR_MASK) { - if (readl(priv->regs + CONTROLLER_STATUS) & TS_PEN_DOWN) + regmap_read(priv->regmap, CONTROLLER_STATUS, >pen_status); + if (priv->pen_status & TS_PEN_DOWN) priv->pen_status = PEN_DOWN_STATUS; else priv->pen_status = PEN_UP_STATUS; - input_report_key(priv->idev, BTN_TOUCH, priv->pen_status); + input_report_key(priv->idev, BTN_TOUCH, priv->pen_status); needs_sync = true; dev_dbg(>pdev->dev, @@ -221,7 +227,7 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, void *data) /* coordinates in FIFO exceed the theshold */ if (intr_status & TS_FIFO_INTR_MASK) { for (i = 0; i < priv->cfg_params.fifo_threshold; i++) { - raw_coordinate = readl(priv->regs + FIFO_DATA); + regmap_read(priv->regmap, FIFO_DATA, _coordinate); if (raw_coordinate == INVALID_COORD) continue; @@ -239,7 +245,7 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, void *data) x = (x >> 4) & 0x0FFF; y = (y >> 4) & 0x0FFF; - /* adjust x y according to lcd tsc mount angle */ + /* Adjust x y according to LCD tsc mount angle. */ if (priv->cfg_params.invert_x) x = priv->cfg_params.max_x - x; @@ -262,9 +268,10 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, void *data) static int iproc_ts_start(struct input_dev *idev) { - struct iproc_ts_priv *priv = input_get_drvdata(idev); u32 val; + u32 mask; int error; + struct iproc_ts_priv *priv = input_get_drvdata(idev); /* Enable clock */ error = clk_prepare_enable(priv->tsc_clk); @@ -279,9 +286,10 @@ static int iproc_ts_start(struct input_dev *idev) * FIFO reaches the int_th value, and pen event(up/down) */ val = TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK; - writel(val, priv->regs + INTERRUPT_MASK); + regmap_update_bits(priv->regmap, INTERRUPT_MASK, val, val); - writel(priv->cfg_params.fifo_threshold, priv->regs + INTERRUPT_THRES); + val = priv->cfg_params.fifo_threshold; + regmap_write(priv->regmap, INTERRUPT_THRES, val); /* Initialize control reg1 */ val = 0; @@ -289,26 +297,23 @@ static int iproc_ts_start(struct input_dev *idev) val |= priv->cfg_params.debounce_timeout << DEBOUNCE_TIMEOUT_SHIFT; val |= priv->cfg_params.settling_timeout <<
[PATCH v5 2/3] input: syscon support in bcm_iproc_tsc driver
In Cygnus SOC touch screen controller registers are shared with ADC and flex timer. Using readl/writel could lead to race condition. So touch screen driver is enhanced to support register access using syscon framework API's to take care of mutually exclusive access. Signed-off-by: Raveendra Padasalagi Reviewed-by: Ray Jui Reviewed-by: Scott Branden Reviewed-by: Arnd Bergmann --- drivers/input/touchscreen/bcm_iproc_tsc.c | 79 +-- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/drivers/input/touchscreen/bcm_iproc_tsc.c b/drivers/input/touchscreen/bcm_iproc_tsc.c index ae460a5c..0fd5f35 100644 --- a/drivers/input/touchscreen/bcm_iproc_tsc.c +++ b/drivers/input/touchscreen/bcm_iproc_tsc.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #define IPROC_TS_NAME "iproc-ts" @@ -88,7 +90,11 @@ #define TS_WIRE_MODE_BITBIT(1) #define dbg_reg(dev, priv, reg) \ - dev_dbg(dev, "%20s= 0x%08x\n", #reg, readl((priv)->regs + reg)) +do { \ + u32 val; \ + regmap_read(priv->regmap, reg, ); \ + dev_dbg(dev, "%20s= 0x%08x\n", #reg, val); \ +} while (0) struct tsc_param { /* Each step is 1024 us. Valid 1-256 */ @@ -141,7 +147,7 @@ struct iproc_ts_priv { struct platform_device *pdev; struct input_dev *idev; - void __iomem *regs; + struct regmap *regmap; struct clk *tsc_clk; int pen_status; @@ -196,22 +202,22 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, void *data) int i; bool needs_sync = false; - intr_status = readl(priv->regs + INTERRUPT_STATUS); - intr_status &= TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK; + regmap_read(priv->regmap, INTERRUPT_STATUS, _status); + intr_status &= (TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK); if (intr_status == 0) return IRQ_NONE; /* Clear all interrupt status bits, write-1-clear */ - writel(intr_status, priv->regs + INTERRUPT_STATUS); - + regmap_write(priv->regmap, INTERRUPT_STATUS, intr_status); /* Pen up/down */ if (intr_status & TS_PEN_INTR_MASK) { - if (readl(priv->regs + CONTROLLER_STATUS) & TS_PEN_DOWN) + regmap_read(priv->regmap, CONTROLLER_STATUS, >pen_status); + if (priv->pen_status & TS_PEN_DOWN) priv->pen_status = PEN_DOWN_STATUS; else priv->pen_status = PEN_UP_STATUS; - input_report_key(priv->idev, BTN_TOUCH, priv->pen_status); + input_report_key(priv->idev, BTN_TOUCH, priv->pen_status); needs_sync = true; dev_dbg(>pdev->dev, @@ -221,7 +227,7 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, void *data) /* coordinates in FIFO exceed the theshold */ if (intr_status & TS_FIFO_INTR_MASK) { for (i = 0; i < priv->cfg_params.fifo_threshold; i++) { - raw_coordinate = readl(priv->regs + FIFO_DATA); + regmap_read(priv->regmap, FIFO_DATA, _coordinate); if (raw_coordinate == INVALID_COORD) continue; @@ -239,7 +245,7 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, void *data) x = (x >> 4) & 0x0FFF; y = (y >> 4) & 0x0FFF; - /* adjust x y according to lcd tsc mount angle */ + /* Adjust x y according to LCD tsc mount angle. */ if (priv->cfg_params.invert_x) x = priv->cfg_params.max_x - x; @@ -262,9 +268,10 @@ static irqreturn_t iproc_touchscreen_interrupt(int irq, void *data) static int iproc_ts_start(struct input_dev *idev) { - struct iproc_ts_priv *priv = input_get_drvdata(idev); u32 val; + u32 mask; int error; + struct iproc_ts_priv *priv = input_get_drvdata(idev); /* Enable clock */ error = clk_prepare_enable(priv->tsc_clk); @@ -279,9 +286,10 @@ static int iproc_ts_start(struct input_dev *idev) * FIFO reaches the int_th value, and pen event(up/down) */ val = TS_PEN_INTR_MASK | TS_FIFO_INTR_MASK; - writel(val, priv->regs + INTERRUPT_MASK); + regmap_update_bits(priv->regmap, INTERRUPT_MASK, val, val); - writel(priv->cfg_params.fifo_threshold, priv->regs + INTERRUPT_THRES); + val = priv->cfg_params.fifo_threshold; + regmap_write(priv->regmap, INTERRUPT_THRES, val); /* Initialize control reg1 */ val = 0; @@ -289,26 +297,23 @@ static int iproc_ts_start(struct input_dev *idev) val |= priv->cfg_params.debounce_timeout << DEBOUNCE_TIMEOUT_SHIFT; val |= priv->cfg_params.settling_timeout << SETTLING_TIMEOUT_SHIFT; val |= priv->cfg_params.touch_timeout << TOUCH_TIMEOUT_SHIFT; - writel(val,
[PATCH v5 3/3] ARM: dts: use syscon in cygnus touchscreen dt node
In Cygnus SOC touch screen controller registers are shared with ADC and flex timer. Using readl/writel could lead to race condition. So touchscreen driver is enhanced to support syscon based register access to take care of mutually exclusive access. This patch enables syscon support in touchscreen driver by adding necessary properties in touchscreen dt node and in addition to this renamed existing "tsc" touchscreen node name to "touchscreen". Signed-off-by: Raveendra PadasalagiReviewed-by: Ray Jui Reviewed-by: Scott Branden --- arch/arm/boot/dts/bcm-cygnus.dtsi | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi index 3878793..b42fe55 100644 --- a/arch/arm/boot/dts/bcm-cygnus.dtsi +++ b/arch/arm/boot/dts/bcm-cygnus.dtsi @@ -351,9 +351,16 @@ < 142 10 1>; }; - touchscreen: tsc@180a6000 { + ts_adc_syscon: ts_adc_syscon@180a6000 { + compatible = "brcm,iproc-ts-adc-syscon", "syscon"; + reg = <0x180a6000 0xc30>; + }; + + touchscreen: touchscreen@180a6000 { compatible = "brcm,iproc-touchscreen"; - reg = <0x180a6000 0x40>; + #address-cells = <1>; + #size-cells = <1>; + ts_syscon = <_adc_syscon>; clocks = <_clks BCM_CYGNUS_ASIU_ADC_CLK>; clock-names = "tsc_clk"; interrupts = ; -- 1.9.1
[PATCH v5 0/3] Syscon support for iProc touchscreen driver
This patchset is based on v4.5-rc3 tag and its tested on Broadcom Cygnus SoC. The patches can be fetched from iproc-tsc-v5 branch of https://github.com/Broadcom/arm64-linux.git Changes since v4: - Fixed odd_ptr_err.cocci script warning Changes since v3: - Renamed touchscreen node "tsc" to "touchscreen" in dt binding document - Added support for syscon only based register access in touch screen driver and removed "regs" based register access. Updated dt binding document to reflect the changes. - Removed "brcm,iproc-touchscreen-syscon" compatible string support in dt binding document and touchscreen driver implementation. Changes since v2: - Omitted '0x' in "tsc node" definition in dt documentation file - Omitted '0x' in "ts_adc_syscon" definition in dt documentation file - Added "brcm,iproc-ts-adc-syscon" compatible string in "ts_adc_syscon" node. Updated dt documentation file to reflect this change. Changes since v1: - Enhanced touchscreen driver to handle syscon based register access if "brcm,iproc-touchscreen-syscon" compatible string is provided in dt - Normal register access is handled through readl and writel API's if "brcm,iproc-touchscreen" compatible string is provided. - Updated touchscreen dt node document to reflect the new changes. - Updated change logs in each patchset to reflect the new changes Raveendra Padasalagi (3): input: cygnus-update touchscreen dt node document input: syscon support in bcm_iproc_tsc driver ARM: dts: use syscon in cygnus touchscreen dt node .../input/touchscreen/brcm,iproc-touchscreen.txt | 21 -- arch/arm/boot/dts/bcm-cygnus.dtsi | 11 ++- drivers/input/touchscreen/bcm_iproc_tsc.c | 79 -- 3 files changed, 69 insertions(+), 42 deletions(-) -- 1.9.1
[PATCH v5 1/3] input: cygnus-update touchscreen dt node document
In Cygnus SOC touch screen controller registers are shared with ADC and flex timer. Using readl/writel could lead to race condition. So touch screen driver is enhanced to support register access using syscon framework API's to take care of mutually exclusive access.In addition to this existing touchscreen node name "tsc" is renamed to "touchscreen". Hence touchscreen dt node bindings document is updated to take care of above changes in the touchscreen driver. Signed-off-by: Raveendra PadasalagiReviewed-by: Ray Jui Reviewed-by: Scott Branden Acked-by: Rob Herring --- .../input/touchscreen/brcm,iproc-touchscreen.txt| 21 - 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt b/Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt index 34e3382..25541f3 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt @@ -2,11 +2,17 @@ Required properties: - compatible: must be "brcm,iproc-touchscreen" -- reg: physical base address of the controller and length of memory mapped - region. +- ts_syscon: handler of syscon node defining physical base + address of the controller and length of memory mapped region. + If this property is selected please make sure MFD_SYSCON config + is enabled in the defconfig file. - clocks: The clock provided by the SOC to driver the tsc - clock-name: name for the clock - interrupts: The touchscreen controller's interrupt +- address-cells: Specify the number of u32 entries needed in child nodes. + Should set to 1. +- size-cells: Specify number of u32 entries needed to specify child nodes size + in reg property. Should set to 1. Optional properties: - scanning_period: Time between scans. Each step is 1024 us. Valid 1-256. @@ -53,13 +59,18 @@ Optional properties: - touchscreen-inverted-x: X axis is inverted (boolean) - touchscreen-inverted-y: Y axis is inverted (boolean) -Example: +Example: An example of touchscreen node - touchscreen: tsc@0x180A6000 { + ts_adc_syscon: ts_adc_syscon@180a6000 { + compatible = "brcm,iproc-ts-adc-syscon","syscon"; + reg = <0x180a6000 0xc30>; + }; + + touchscreen: touchscreen@180A6000 { compatible = "brcm,iproc-touchscreen"; #address-cells = <1>; #size-cells = <1>; - reg = <0x180A6000 0x40>; + ts_syscon = <_adc_syscon>; clocks = <_clk>; clock-names = "tsc_clk"; interrupts = ; -- 1.9.1
[PATCH v5 3/3] ARM: dts: use syscon in cygnus touchscreen dt node
In Cygnus SOC touch screen controller registers are shared with ADC and flex timer. Using readl/writel could lead to race condition. So touchscreen driver is enhanced to support syscon based register access to take care of mutually exclusive access. This patch enables syscon support in touchscreen driver by adding necessary properties in touchscreen dt node and in addition to this renamed existing "tsc" touchscreen node name to "touchscreen". Signed-off-by: Raveendra Padasalagi Reviewed-by: Ray Jui Reviewed-by: Scott Branden --- arch/arm/boot/dts/bcm-cygnus.dtsi | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi index 3878793..b42fe55 100644 --- a/arch/arm/boot/dts/bcm-cygnus.dtsi +++ b/arch/arm/boot/dts/bcm-cygnus.dtsi @@ -351,9 +351,16 @@ < 142 10 1>; }; - touchscreen: tsc@180a6000 { + ts_adc_syscon: ts_adc_syscon@180a6000 { + compatible = "brcm,iproc-ts-adc-syscon", "syscon"; + reg = <0x180a6000 0xc30>; + }; + + touchscreen: touchscreen@180a6000 { compatible = "brcm,iproc-touchscreen"; - reg = <0x180a6000 0x40>; + #address-cells = <1>; + #size-cells = <1>; + ts_syscon = <_adc_syscon>; clocks = <_clks BCM_CYGNUS_ASIU_ADC_CLK>; clock-names = "tsc_clk"; interrupts = ; -- 1.9.1
[PATCH v5 0/3] Syscon support for iProc touchscreen driver
This patchset is based on v4.5-rc3 tag and its tested on Broadcom Cygnus SoC. The patches can be fetched from iproc-tsc-v5 branch of https://github.com/Broadcom/arm64-linux.git Changes since v4: - Fixed odd_ptr_err.cocci script warning Changes since v3: - Renamed touchscreen node "tsc" to "touchscreen" in dt binding document - Added support for syscon only based register access in touch screen driver and removed "regs" based register access. Updated dt binding document to reflect the changes. - Removed "brcm,iproc-touchscreen-syscon" compatible string support in dt binding document and touchscreen driver implementation. Changes since v2: - Omitted '0x' in "tsc node" definition in dt documentation file - Omitted '0x' in "ts_adc_syscon" definition in dt documentation file - Added "brcm,iproc-ts-adc-syscon" compatible string in "ts_adc_syscon" node. Updated dt documentation file to reflect this change. Changes since v1: - Enhanced touchscreen driver to handle syscon based register access if "brcm,iproc-touchscreen-syscon" compatible string is provided in dt - Normal register access is handled through readl and writel API's if "brcm,iproc-touchscreen" compatible string is provided. - Updated touchscreen dt node document to reflect the new changes. - Updated change logs in each patchset to reflect the new changes Raveendra Padasalagi (3): input: cygnus-update touchscreen dt node document input: syscon support in bcm_iproc_tsc driver ARM: dts: use syscon in cygnus touchscreen dt node .../input/touchscreen/brcm,iproc-touchscreen.txt | 21 -- arch/arm/boot/dts/bcm-cygnus.dtsi | 11 ++- drivers/input/touchscreen/bcm_iproc_tsc.c | 79 -- 3 files changed, 69 insertions(+), 42 deletions(-) -- 1.9.1
[PATCH v5 1/3] input: cygnus-update touchscreen dt node document
In Cygnus SOC touch screen controller registers are shared with ADC and flex timer. Using readl/writel could lead to race condition. So touch screen driver is enhanced to support register access using syscon framework API's to take care of mutually exclusive access.In addition to this existing touchscreen node name "tsc" is renamed to "touchscreen". Hence touchscreen dt node bindings document is updated to take care of above changes in the touchscreen driver. Signed-off-by: Raveendra Padasalagi Reviewed-by: Ray Jui Reviewed-by: Scott Branden Acked-by: Rob Herring --- .../input/touchscreen/brcm,iproc-touchscreen.txt| 21 - 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt b/Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt index 34e3382..25541f3 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/brcm,iproc-touchscreen.txt @@ -2,11 +2,17 @@ Required properties: - compatible: must be "brcm,iproc-touchscreen" -- reg: physical base address of the controller and length of memory mapped - region. +- ts_syscon: handler of syscon node defining physical base + address of the controller and length of memory mapped region. + If this property is selected please make sure MFD_SYSCON config + is enabled in the defconfig file. - clocks: The clock provided by the SOC to driver the tsc - clock-name: name for the clock - interrupts: The touchscreen controller's interrupt +- address-cells: Specify the number of u32 entries needed in child nodes. + Should set to 1. +- size-cells: Specify number of u32 entries needed to specify child nodes size + in reg property. Should set to 1. Optional properties: - scanning_period: Time between scans. Each step is 1024 us. Valid 1-256. @@ -53,13 +59,18 @@ Optional properties: - touchscreen-inverted-x: X axis is inverted (boolean) - touchscreen-inverted-y: Y axis is inverted (boolean) -Example: +Example: An example of touchscreen node - touchscreen: tsc@0x180A6000 { + ts_adc_syscon: ts_adc_syscon@180a6000 { + compatible = "brcm,iproc-ts-adc-syscon","syscon"; + reg = <0x180a6000 0xc30>; + }; + + touchscreen: touchscreen@180A6000 { compatible = "brcm,iproc-touchscreen"; #address-cells = <1>; #size-cells = <1>; - reg = <0x180A6000 0x40>; + ts_syscon = <_adc_syscon>; clocks = <_clk>; clock-names = "tsc_clk"; interrupts = ; -- 1.9.1
call attention to review
Hi, I am Lijun Ou. I have sent the PATCH v4 of HiSilicon RoCE driver at March 22, 2016. if you are convenient, please help to review. Welcome to give your reviewing. thanks Lijun Ou
call attention to review
Hi, I am Lijun Ou. I have sent the PATCH v4 of HiSilicon RoCE driver at March 22, 2016. if you are convenient, please help to review. Welcome to give your reviewing. thanks Lijun Ou
[PATCH] lib/spinlock_debug: Prevent unnecessary recursive spin_dump()
For your information, there is another patch I posted which looks similar to this patch, but is totally different, that is, https://lkml.org/lkml/2016/3/11/192, trying to solve a deadlock problem. In that patch, I tried to make printk async to avoid the deadlock but I found Sergey and Jan were already working on the asynchronous printk(). That is, https://lkml.org/lkml/2016/3/23/316. Thus I decided to wait the work to be done and to work on my patch again based on the patch by Sergey and Jan. On the other hand, this patch is not for avoiding the deadlock, but for avoiding unnecessary recursion. See the backtrace shown below. -8<- >From c4be9976ec21debc3883fc2d97ba4a905102876f Mon Sep 17 00:00:00 2001 From: Byungchul ParkDate: Thu, 24 Mar 2016 11:37:25 +0900 Subject: [PATCH] lib/spinlock_debug: Prevent unnecessary recursive spin_dump() Printing "lockup suspected" for the same lock more than once is meaningless. Furtheremore, it can cause an indefinite recursion if it occures within a printk(). For example, printk spin_lock(A) spin_dump // lockup suspected for A printk spin_lock(A) spin_dump // lockup suspected for A ... indefinitely where "A" can be any lock which is used within printk(). The recursion can be stopped if the lock causing the lockup is released. However this warning messages repeated and accumulated unnecessarily might eat off the printk log buffer. And it also consumes away the cpu time unnecessarily. We have to avoid this situation. Of course this patch cannot detect the recursion perfectly. In a rare case, it can print the "lockup suspected" message recursively several times. But at least we can detect and prevent unnecessary indefinite recursion without missing any important printing. Detecting perfectly requires to make the code more complex and use more memory. Who care? Signed-off-by: Byungchul Park --- kernel/locking/spinlock_debug.c | 31 ++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/kernel/locking/spinlock_debug.c b/kernel/locking/spinlock_debug.c index 0374a59..653eea9 100644 --- a/kernel/locking/spinlock_debug.c +++ b/kernel/locking/spinlock_debug.c @@ -103,6 +103,31 @@ static inline void debug_spin_unlock(raw_spinlock_t *lock) lock->owner_cpu = -1; } +static raw_spinlock_t *sus_lock; +static unsigned int sus_cpu = -1; +static pid_t sus_pid = -1; + +static inline void enter_lockup_suspected(raw_spinlock_t *lock) +{ + sus_lock = lock; + sus_cpu = raw_smp_processor_id(); + sus_pid = task_pid_nr(current); +} + +static inline void exit_lockup_suspected(raw_spinlock_t *lock) +{ + sus_lock = NULL; + sus_cpu = -1; + sus_pid = -1; +} + +static inline int detect_recursive_lockup_suspected(raw_spinlock_t *lock) +{ + return sus_lock == lock && + sus_cpu == raw_smp_processor_id() && + sus_pid == task_pid_nr(current); +} + static void __spin_lock_debug(raw_spinlock_t *lock) { u64 i; @@ -114,7 +139,11 @@ static void __spin_lock_debug(raw_spinlock_t *lock) __delay(1); } /* lockup suspected: */ - spin_dump(lock, "lockup suspected"); + if (likely(!detect_recursive_lockup_suspected(lock))) { + enter_lockup_suspected(lock); + spin_dump(lock, "lockup suspected"); + exit_lockup_suspected(lock); + } #ifdef CONFIG_SMP trigger_all_cpu_backtrace(); #endif -- 1.9.1
[PATCH] lib/spinlock_debug: Prevent unnecessary recursive spin_dump()
For your information, there is another patch I posted which looks similar to this patch, but is totally different, that is, https://lkml.org/lkml/2016/3/11/192, trying to solve a deadlock problem. In that patch, I tried to make printk async to avoid the deadlock but I found Sergey and Jan were already working on the asynchronous printk(). That is, https://lkml.org/lkml/2016/3/23/316. Thus I decided to wait the work to be done and to work on my patch again based on the patch by Sergey and Jan. On the other hand, this patch is not for avoiding the deadlock, but for avoiding unnecessary recursion. See the backtrace shown below. -8<- >From c4be9976ec21debc3883fc2d97ba4a905102876f Mon Sep 17 00:00:00 2001 From: Byungchul Park Date: Thu, 24 Mar 2016 11:37:25 +0900 Subject: [PATCH] lib/spinlock_debug: Prevent unnecessary recursive spin_dump() Printing "lockup suspected" for the same lock more than once is meaningless. Furtheremore, it can cause an indefinite recursion if it occures within a printk(). For example, printk spin_lock(A) spin_dump // lockup suspected for A printk spin_lock(A) spin_dump // lockup suspected for A ... indefinitely where "A" can be any lock which is used within printk(). The recursion can be stopped if the lock causing the lockup is released. However this warning messages repeated and accumulated unnecessarily might eat off the printk log buffer. And it also consumes away the cpu time unnecessarily. We have to avoid this situation. Of course this patch cannot detect the recursion perfectly. In a rare case, it can print the "lockup suspected" message recursively several times. But at least we can detect and prevent unnecessary indefinite recursion without missing any important printing. Detecting perfectly requires to make the code more complex and use more memory. Who care? Signed-off-by: Byungchul Park --- kernel/locking/spinlock_debug.c | 31 ++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/kernel/locking/spinlock_debug.c b/kernel/locking/spinlock_debug.c index 0374a59..653eea9 100644 --- a/kernel/locking/spinlock_debug.c +++ b/kernel/locking/spinlock_debug.c @@ -103,6 +103,31 @@ static inline void debug_spin_unlock(raw_spinlock_t *lock) lock->owner_cpu = -1; } +static raw_spinlock_t *sus_lock; +static unsigned int sus_cpu = -1; +static pid_t sus_pid = -1; + +static inline void enter_lockup_suspected(raw_spinlock_t *lock) +{ + sus_lock = lock; + sus_cpu = raw_smp_processor_id(); + sus_pid = task_pid_nr(current); +} + +static inline void exit_lockup_suspected(raw_spinlock_t *lock) +{ + sus_lock = NULL; + sus_cpu = -1; + sus_pid = -1; +} + +static inline int detect_recursive_lockup_suspected(raw_spinlock_t *lock) +{ + return sus_lock == lock && + sus_cpu == raw_smp_processor_id() && + sus_pid == task_pid_nr(current); +} + static void __spin_lock_debug(raw_spinlock_t *lock) { u64 i; @@ -114,7 +139,11 @@ static void __spin_lock_debug(raw_spinlock_t *lock) __delay(1); } /* lockup suspected: */ - spin_dump(lock, "lockup suspected"); + if (likely(!detect_recursive_lockup_suspected(lock))) { + enter_lockup_suspected(lock); + spin_dump(lock, "lockup suspected"); + exit_lockup_suspected(lock); + } #ifdef CONFIG_SMP trigger_all_cpu_backtrace(); #endif -- 1.9.1
Re: linux-next: Tree for Mar 24
Hi all, On Thu, 24 Mar 2016 13:09:41 +1100 Stephen Rothwellwrote: > > Please do not add any v4.7 related material to your linux-next included > trees until after v4.6-rc1 is released. I forgot to say that there will be no linux-next release tomorrow or Monday. -- Cheers, Stephen Rothwell
Re: linux-next: Tree for Mar 24
Hi all, On Thu, 24 Mar 2016 13:09:41 +1100 Stephen Rothwell wrote: > > Please do not add any v4.7 related material to your linux-next included > trees until after v4.6-rc1 is released. I forgot to say that there will be no linux-next release tomorrow or Monday. -- Cheers, Stephen Rothwell
Re:¸´£ºProces denture tools
Dear Sir Hello! Our company is the Guangzhou Honda and China FAW suppliers. We have been providing quality products and services for them. Our company's main products: Graphite machining end mill The denture machining tool Zirconia processing tool PCD tools CNC inserts Milling toolholder Boron carbide nozzles Mould parts Guide bush and collet Dental with titanium screws, this product quality has certification ISO13485 of the German T¨¹V We will frequently introduce new products, please pay attention www.jch-tools.com. We have been providing our customers with high quality products and quality service, we performed continuous processing technology improvement, continuing to reduce the production cost, to provide customers maximize profits. Our products are exported around the world, has a good customer evaluation. Our quality service, has a good customer evaluation. If you are interested in, you can test some samples for confirming our products quality, I believe we will have pleasant cooperation in the near future. Best regards! FANG SHENZHEN KALEAD TOOLS CO.,LTD Shenzhen Surmount Tools Co., Ltd TEL: 86-0755-27261985 FAX: 86-0755-27261895 Email: s...@jch-tools.com Web: www.jch-tools.com
Re:¸´£ºProces denture tools
Dear Sir Hello! Our company is the Guangzhou Honda and China FAW suppliers. We have been providing quality products and services for them. Our company's main products: Graphite machining end mill The denture machining tool Zirconia processing tool PCD tools CNC inserts Milling toolholder Boron carbide nozzles Mould parts Guide bush and collet Dental with titanium screws, this product quality has certification ISO13485 of the German T¨¹V We will frequently introduce new products, please pay attention www.jch-tools.com. We have been providing our customers with high quality products and quality service, we performed continuous processing technology improvement, continuing to reduce the production cost, to provide customers maximize profits. Our products are exported around the world, has a good customer evaluation. Our quality service, has a good customer evaluation. If you are interested in, you can test some samples for confirming our products quality, I believe we will have pleasant cooperation in the near future. Best regards! FANG SHENZHEN KALEAD TOOLS CO.,LTD Shenzhen Surmount Tools Co., Ltd TEL: 86-0755-27261985 FAX: 86-0755-27261895 Email: s...@jch-tools.com Web: www.jch-tools.com
[PATCH 1/2] intel_idle: prevent SKL-H boot failure when C8+C9+C10 enabled
From: Len BrownSome SKL-H configurations require "intel_idle.max_cstate=7" to boot. While that is an effective workaround, it disables C10. This patch detects the problematic configuration, and disables C8 and C9, keeping C10 enabled. Note that enabling SGX in BIOS SETUP can also prevent this issue, if the system BIOS provides that option. https://bugzilla.kernel.org/show_bug.cgi?id=109081 "Freezes with Intel i7 6700HQ (Skylake), unless intel_idle.max_cstate=7" Signed-off-by: Len Brown Cc: sta...@vger.kernel.org --- drivers/idle/intel_idle.c | 108 -- 1 file changed, 86 insertions(+), 22 deletions(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index cd4510a..146eed70b 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -65,7 +65,7 @@ #include #include -#define INTEL_IDLE_VERSION "0.4" +#define INTEL_IDLE_VERSION "0.4.1" #define PREFIX "intel_idle: " static struct cpuidle_driver intel_idle_driver = { @@ -994,36 +994,92 @@ static void intel_idle_cpuidle_devices_uninit(void) } /* - * intel_idle_state_table_update() - * - * Update the default state_table for this CPU-id + * ivt_idle_state_table_update(void) * - * Currently used to access tuned IVT multi-socket targets + * Tune IVT multi-socket targets * Assumption: num_sockets == (max_package_num + 1) */ -void intel_idle_state_table_update(void) +static void ivt_idle_state_table_update(void) { /* IVT uses a different table for 1-2, 3-4, and > 4 sockets */ - if (boot_cpu_data.x86_model == 0x3e) { /* IVT */ - int cpu, package_num, num_sockets = 1; - - for_each_online_cpu(cpu) { - package_num = topology_physical_package_id(cpu); - if (package_num + 1 > num_sockets) { - num_sockets = package_num + 1; - - if (num_sockets > 4) { - cpuidle_state_table = ivt_cstates_8s; - return; - } + int cpu, package_num, num_sockets = 1; + + for_each_online_cpu(cpu) { + package_num = topology_physical_package_id(cpu); + if (package_num + 1 > num_sockets) { + num_sockets = package_num + 1; + + if (num_sockets > 4) { + cpuidle_state_table = ivt_cstates_8s; + return; } } + } + + if (num_sockets > 2) + cpuidle_state_table = ivt_cstates_4s; + + /* else, 1 and 2 socket systems use default ivt_cstates */ +} +/* + * sklh_idle_state_table_update(void) + * + * On SKL-H (model 0x5e) disable C8 and C9 if: + * C10 is enabled and SGX disabled + */ +static void sklh_idle_state_table_update(void) +{ + unsigned long long msr; + unsigned int eax, ebx, ecx, edx; + + + /* if PC10 disabled via cmdline intel_idle.max_cstate=7 or shallower */ + if (max_cstate <= 7) + return; + + /* if PC10 not present in CPUID.MWAIT.EDX */ + if ((mwait_substates & (0xF << 28)) == 0) + return; + + rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr); + + /* PC10 is not enabled in PKG C-state limit */ + if ((msr & 0xF) != 8) + return; + + ecx = 0; + cpuid(7, , , , ); + + /* if SGX is present */ + if (ebx & (1 << 2)) { - if (num_sockets > 2) - cpuidle_state_table = ivt_cstates_4s; - /* else, 1 and 2 socket systems use default ivt_cstates */ + rdmsrl(MSR_IA32_FEATURE_CONTROL, msr); + + /* if SGX is enabled */ + if (msr & (1 << 18)) + return; + } + + skl_cstates[5].disabled = 1;/* C8-SKL */ + skl_cstates[6].disabled = 1;/* C9-SKL */ +} +/* + * intel_idle_state_table_update() + * + * Update the default state_table for this CPU-id + */ + +static void intel_idle_state_table_update(void) +{ + switch (boot_cpu_data.x86_model) { + + case 0x3e: /* IVT */ + ivt_idle_state_table_update(); + break; + case 0x5e: /* SKL-H */ + sklh_idle_state_table_update(); + break; } - return; } /* @@ -1063,6 +1119,14 @@ static int __init intel_idle_cpuidle_driver_init(void) if (num_substates == 0) continue; + /* if state marked as disabled, skip it */ + if (cpuidle_state_table[cstate].disabled != 0) { + pr_debug(PREFIX "state %s is disabled", + cpuidle_state_table[cstate].name); + continue; + } + + if (((mwait_cstate + 1) > 2)
[PATCH 1/2] intel_idle: prevent SKL-H boot failure when C8+C9+C10 enabled
From: Len Brown Some SKL-H configurations require "intel_idle.max_cstate=7" to boot. While that is an effective workaround, it disables C10. This patch detects the problematic configuration, and disables C8 and C9, keeping C10 enabled. Note that enabling SGX in BIOS SETUP can also prevent this issue, if the system BIOS provides that option. https://bugzilla.kernel.org/show_bug.cgi?id=109081 "Freezes with Intel i7 6700HQ (Skylake), unless intel_idle.max_cstate=7" Signed-off-by: Len Brown Cc: sta...@vger.kernel.org --- drivers/idle/intel_idle.c | 108 -- 1 file changed, 86 insertions(+), 22 deletions(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index cd4510a..146eed70b 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -65,7 +65,7 @@ #include #include -#define INTEL_IDLE_VERSION "0.4" +#define INTEL_IDLE_VERSION "0.4.1" #define PREFIX "intel_idle: " static struct cpuidle_driver intel_idle_driver = { @@ -994,36 +994,92 @@ static void intel_idle_cpuidle_devices_uninit(void) } /* - * intel_idle_state_table_update() - * - * Update the default state_table for this CPU-id + * ivt_idle_state_table_update(void) * - * Currently used to access tuned IVT multi-socket targets + * Tune IVT multi-socket targets * Assumption: num_sockets == (max_package_num + 1) */ -void intel_idle_state_table_update(void) +static void ivt_idle_state_table_update(void) { /* IVT uses a different table for 1-2, 3-4, and > 4 sockets */ - if (boot_cpu_data.x86_model == 0x3e) { /* IVT */ - int cpu, package_num, num_sockets = 1; - - for_each_online_cpu(cpu) { - package_num = topology_physical_package_id(cpu); - if (package_num + 1 > num_sockets) { - num_sockets = package_num + 1; - - if (num_sockets > 4) { - cpuidle_state_table = ivt_cstates_8s; - return; - } + int cpu, package_num, num_sockets = 1; + + for_each_online_cpu(cpu) { + package_num = topology_physical_package_id(cpu); + if (package_num + 1 > num_sockets) { + num_sockets = package_num + 1; + + if (num_sockets > 4) { + cpuidle_state_table = ivt_cstates_8s; + return; } } + } + + if (num_sockets > 2) + cpuidle_state_table = ivt_cstates_4s; + + /* else, 1 and 2 socket systems use default ivt_cstates */ +} +/* + * sklh_idle_state_table_update(void) + * + * On SKL-H (model 0x5e) disable C8 and C9 if: + * C10 is enabled and SGX disabled + */ +static void sklh_idle_state_table_update(void) +{ + unsigned long long msr; + unsigned int eax, ebx, ecx, edx; + + + /* if PC10 disabled via cmdline intel_idle.max_cstate=7 or shallower */ + if (max_cstate <= 7) + return; + + /* if PC10 not present in CPUID.MWAIT.EDX */ + if ((mwait_substates & (0xF << 28)) == 0) + return; + + rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr); + + /* PC10 is not enabled in PKG C-state limit */ + if ((msr & 0xF) != 8) + return; + + ecx = 0; + cpuid(7, , , , ); + + /* if SGX is present */ + if (ebx & (1 << 2)) { - if (num_sockets > 2) - cpuidle_state_table = ivt_cstates_4s; - /* else, 1 and 2 socket systems use default ivt_cstates */ + rdmsrl(MSR_IA32_FEATURE_CONTROL, msr); + + /* if SGX is enabled */ + if (msr & (1 << 18)) + return; + } + + skl_cstates[5].disabled = 1;/* C8-SKL */ + skl_cstates[6].disabled = 1;/* C9-SKL */ +} +/* + * intel_idle_state_table_update() + * + * Update the default state_table for this CPU-id + */ + +static void intel_idle_state_table_update(void) +{ + switch (boot_cpu_data.x86_model) { + + case 0x3e: /* IVT */ + ivt_idle_state_table_update(); + break; + case 0x5e: /* SKL-H */ + sklh_idle_state_table_update(); + break; } - return; } /* @@ -1063,6 +1119,14 @@ static int __init intel_idle_cpuidle_driver_init(void) if (num_substates == 0) continue; + /* if state marked as disabled, skip it */ + if (cpuidle_state_table[cstate].disabled != 0) { + pr_debug(PREFIX "state %s is disabled", + cpuidle_state_table[cstate].name); + continue; + } + + if (((mwait_cstate + 1) > 2) &&
[PATCH 2/2] intel_idle: Support for Intel Xeon Phi Processor x200 Product Family
From: Dasaratharaman ChandramouliEnables "Intel(R) Xeon Phi(TM) Processor x200 Product Family" support, formerly code-named KNL. It is based on modified Intel Atom Silvermont microarchitecture. Signed-off-by: Dasaratharaman Chandramouli [micah.bar...@intel.com: adjusted values of residency and latency] Signed-off-by: Micah Barany [hubert.chrzan...@intel.com: removed deprecated CPUIDLE_FLAG_TIME_VALID flag] Signed-off-by: Hubert Chrzaniuk Signed-off-by: Pawel Karczewski Signed-off-by: Len Brown --- drivers/idle/intel_idle.c | 25 + 1 file changed, 25 insertions(+) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 146eed70b..ba947df 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -716,6 +716,26 @@ static struct cpuidle_state avn_cstates[] = { { .enter = NULL } }; +static struct cpuidle_state knl_cstates[] = { + { + .name = "C1-KNL", + .desc = "MWAIT 0x00", + .flags = MWAIT2flg(0x00), + .exit_latency = 1, + .target_residency = 2, + .enter = _idle, + .enter_freeze = intel_idle_freeze }, + { + .name = "C6-KNL", + .desc = "MWAIT 0x10", + .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 120, + .target_residency = 500, + .enter = _idle, + .enter_freeze = intel_idle_freeze }, + { + .enter = NULL } +}; /** * intel_idle @@ -890,6 +910,10 @@ static const struct idle_cpu idle_cpu_avn = { .disable_promotion_to_c1e = true, }; +static const struct idle_cpu idle_cpu_knl = { + .state_table = knl_cstates, +}; + #define ICPU(model, cpu) \ { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long) } @@ -921,6 +945,7 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { ICPU(0x56, idle_cpu_bdw), ICPU(0x4e, idle_cpu_skl), ICPU(0x5e, idle_cpu_skl), + ICPU(0x57, idle_cpu_knl), {} }; MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); -- 2.7.1.339.g0233b80
[PATCH 2/2] intel_idle: Support for Intel Xeon Phi Processor x200 Product Family
From: Dasaratharaman Chandramouli Enables "Intel(R) Xeon Phi(TM) Processor x200 Product Family" support, formerly code-named KNL. It is based on modified Intel Atom Silvermont microarchitecture. Signed-off-by: Dasaratharaman Chandramouli [micah.bar...@intel.com: adjusted values of residency and latency] Signed-off-by: Micah Barany [hubert.chrzan...@intel.com: removed deprecated CPUIDLE_FLAG_TIME_VALID flag] Signed-off-by: Hubert Chrzaniuk Signed-off-by: Pawel Karczewski Signed-off-by: Len Brown --- drivers/idle/intel_idle.c | 25 + 1 file changed, 25 insertions(+) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 146eed70b..ba947df 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -716,6 +716,26 @@ static struct cpuidle_state avn_cstates[] = { { .enter = NULL } }; +static struct cpuidle_state knl_cstates[] = { + { + .name = "C1-KNL", + .desc = "MWAIT 0x00", + .flags = MWAIT2flg(0x00), + .exit_latency = 1, + .target_residency = 2, + .enter = _idle, + .enter_freeze = intel_idle_freeze }, + { + .name = "C6-KNL", + .desc = "MWAIT 0x10", + .flags = MWAIT2flg(0x10) | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 120, + .target_residency = 500, + .enter = _idle, + .enter_freeze = intel_idle_freeze }, + { + .enter = NULL } +}; /** * intel_idle @@ -890,6 +910,10 @@ static const struct idle_cpu idle_cpu_avn = { .disable_promotion_to_c1e = true, }; +static const struct idle_cpu idle_cpu_knl = { + .state_table = knl_cstates, +}; + #define ICPU(model, cpu) \ { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long) } @@ -921,6 +945,7 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = { ICPU(0x56, idle_cpu_bdw), ICPU(0x4e, idle_cpu_skl), ICPU(0x5e, idle_cpu_skl), + ICPU(0x57, idle_cpu_knl), {} }; MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); -- 2.7.1.339.g0233b80
[PATCH 0/2] 2 cpuidle patches for this merge window
[PATCH 1/2] intel_idle: prevent SKL-H boot failure when C8+C9+C10 ... fixes a boot hang, and needs to got to .stable [PATCH 2/2] intel_idle: Support for Intel Xeon Phi Processor x200 ... adds new platform support Please let me know if you see any trouble with them. thanks, Len Brown, Intel Open Source Technology Center
[PATCH 0/2] 2 cpuidle patches for this merge window
[PATCH 1/2] intel_idle: prevent SKL-H boot failure when C8+C9+C10 ... fixes a boot hang, and needs to got to .stable [PATCH 2/2] intel_idle: Support for Intel Xeon Phi Processor x200 ... adds new platform support Please let me know if you see any trouble with them. thanks, Len Brown, Intel Open Source Technology Center
[PATCH 0/2] ARM: cpuidle: bug fix and a trivial improvement
There's one corner case need to be fixed: !cpuidle_ops[cpu].init. patch1 tries to address this corner case. patch2 tries to improve arm_cpuidle_suspend() a bit by moving .suspend check into arm_cpuidle_init(). Jisheng Zhang (2): ARM: cpuidle: fix !cpuidle_ops[cpu].init case during init ARM: cpuidle: make arm_cpuidle_suspend() a bit more efficient arch/arm/kernel/cpuidle.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) -- 2.8.0.rc3
[PATCH 0/2] ARM: cpuidle: bug fix and a trivial improvement
There's one corner case need to be fixed: !cpuidle_ops[cpu].init. patch1 tries to address this corner case. patch2 tries to improve arm_cpuidle_suspend() a bit by moving .suspend check into arm_cpuidle_init(). Jisheng Zhang (2): ARM: cpuidle: fix !cpuidle_ops[cpu].init case during init ARM: cpuidle: make arm_cpuidle_suspend() a bit more efficient arch/arm/kernel/cpuidle.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) -- 2.8.0.rc3
[PATCH 2/2] ARM: cpuidle: make arm_cpuidle_suspend() a bit more efficient
Currently, we check cpuidle_ops.suspend every time when entering a low-power idle state. But this check could be avoided in this hot path by moving it into arm_cpuidle_init() to reduce arm_cpuidle_suspend() overhead a bit. Signed-off-by: Jisheng Zhang--- arch/arm/kernel/cpuidle.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c index f108d8f..bf68d49 100644 --- a/arch/arm/kernel/cpuidle.c +++ b/arch/arm/kernel/cpuidle.c @@ -52,13 +52,9 @@ int arm_cpuidle_simple_enter(struct cpuidle_device *dev, */ int arm_cpuidle_suspend(int index) { - int ret = -EOPNOTSUPP; int cpu = smp_processor_id(); - if (cpuidle_ops[cpu].suspend) - ret = cpuidle_ops[cpu].suspend(index); - - return ret; + return cpuidle_ops[cpu].suspend(index); } /** @@ -144,7 +140,7 @@ int __init arm_cpuidle_init(int cpu) ret = arm_cpuidle_read_ops(cpu_node, cpu); if (!ret) { - if (cpuidle_ops[cpu].init) + if (cpuidle_ops[cpu].init && cpuidle_ops[cpu].suspend) ret = cpuidle_ops[cpu].init(cpu_node, cpu); else ret = -EOPNOTSUPP; -- 2.8.0.rc3
[PATCH 1/2] ARM: cpuidle: fix !cpuidle_ops[cpu].init case during init
Let's assume cpuidle_ops exists but it doesn't implement the according init member, current arm_cpuidle_init() will return success to its caller, but in fact it should return -EOPNOTSUPP. Signed-off-by: Jisheng Zhang--- arch/arm/kernel/cpuidle.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c index 703926e..f108d8f 100644 --- a/arch/arm/kernel/cpuidle.c +++ b/arch/arm/kernel/cpuidle.c @@ -143,8 +143,12 @@ int __init arm_cpuidle_init(int cpu) return -ENODEV; ret = arm_cpuidle_read_ops(cpu_node, cpu); - if (!ret && cpuidle_ops[cpu].init) - ret = cpuidle_ops[cpu].init(cpu_node, cpu); + if (!ret) { + if (cpuidle_ops[cpu].init) + ret = cpuidle_ops[cpu].init(cpu_node, cpu); + else + ret = -EOPNOTSUPP; + } of_node_put(cpu_node); -- 2.8.0.rc3
[PATCH 2/2] ARM: cpuidle: make arm_cpuidle_suspend() a bit more efficient
Currently, we check cpuidle_ops.suspend every time when entering a low-power idle state. But this check could be avoided in this hot path by moving it into arm_cpuidle_init() to reduce arm_cpuidle_suspend() overhead a bit. Signed-off-by: Jisheng Zhang --- arch/arm/kernel/cpuidle.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c index f108d8f..bf68d49 100644 --- a/arch/arm/kernel/cpuidle.c +++ b/arch/arm/kernel/cpuidle.c @@ -52,13 +52,9 @@ int arm_cpuidle_simple_enter(struct cpuidle_device *dev, */ int arm_cpuidle_suspend(int index) { - int ret = -EOPNOTSUPP; int cpu = smp_processor_id(); - if (cpuidle_ops[cpu].suspend) - ret = cpuidle_ops[cpu].suspend(index); - - return ret; + return cpuidle_ops[cpu].suspend(index); } /** @@ -144,7 +140,7 @@ int __init arm_cpuidle_init(int cpu) ret = arm_cpuidle_read_ops(cpu_node, cpu); if (!ret) { - if (cpuidle_ops[cpu].init) + if (cpuidle_ops[cpu].init && cpuidle_ops[cpu].suspend) ret = cpuidle_ops[cpu].init(cpu_node, cpu); else ret = -EOPNOTSUPP; -- 2.8.0.rc3
[PATCH 1/2] ARM: cpuidle: fix !cpuidle_ops[cpu].init case during init
Let's assume cpuidle_ops exists but it doesn't implement the according init member, current arm_cpuidle_init() will return success to its caller, but in fact it should return -EOPNOTSUPP. Signed-off-by: Jisheng Zhang --- arch/arm/kernel/cpuidle.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c index 703926e..f108d8f 100644 --- a/arch/arm/kernel/cpuidle.c +++ b/arch/arm/kernel/cpuidle.c @@ -143,8 +143,12 @@ int __init arm_cpuidle_init(int cpu) return -ENODEV; ret = arm_cpuidle_read_ops(cpu_node, cpu); - if (!ret && cpuidle_ops[cpu].init) - ret = cpuidle_ops[cpu].init(cpu_node, cpu); + if (!ret) { + if (cpuidle_ops[cpu].init) + ret = cpuidle_ops[cpu].init(cpu_node, cpu); + else + ret = -EOPNOTSUPP; + } of_node_put(cpu_node); -- 2.8.0.rc3
[PATCH 2/2] arm64: cpuidle: make arm_cpuidle_suspend() a bit more efficient
Currently, we check cpu_ops->cpu_suspend every time when entering a low-power idle state. But this check could be avoided in this hot path by moving it into arm_cpuidle_init() to reduce arm_cpuidle_suspend() overhead a bit. Signed-off-by: Jisheng Zhang--- arch/arm64/kernel/cpuidle.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c index bd57c59..e11857f 100644 --- a/arch/arm64/kernel/cpuidle.c +++ b/arch/arm64/kernel/cpuidle.c @@ -19,7 +19,8 @@ int __init arm_cpuidle_init(unsigned int cpu) { int ret = -EOPNOTSUPP; - if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_init_idle) + if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_suspend && + cpu_ops[cpu]->cpu_init_idle) ret = cpu_ops[cpu]->cpu_init_idle(cpu); return ret; @@ -36,10 +37,5 @@ int arm_cpuidle_suspend(int index) { int cpu = smp_processor_id(); - /* -* If suspend has not been initialized, cpu_suspend call fails early. -*/ - if (!cpu_ops[cpu]->cpu_suspend) - return -EOPNOTSUPP; return cpu_ops[cpu]->cpu_suspend(index); } -- 2.8.0.rc3
[PATCH 1/2] arm64: cpuidle: remove cpu_ops check from arm_cpuidle_suspend()
If cpu_ops has not been registered, arm_cpuidle_init() will return -EOPNOTSUPP, so arm_cpuidle_suspend() will never have chance to run. In other word, the cpu_ops check can be avoid. Signed-off-by: Jisheng Zhang--- arch/arm64/kernel/cpuidle.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c index 9047cab6..bd57c59 100644 --- a/arch/arm64/kernel/cpuidle.c +++ b/arch/arm64/kernel/cpuidle.c @@ -37,10 +37,9 @@ int arm_cpuidle_suspend(int index) int cpu = smp_processor_id(); /* -* If cpu_ops have not been registered or suspend -* has not been initialized, cpu_suspend call fails early. +* If suspend has not been initialized, cpu_suspend call fails early. */ - if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_suspend) + if (!cpu_ops[cpu]->cpu_suspend) return -EOPNOTSUPP; return cpu_ops[cpu]->cpu_suspend(index); } -- 2.8.0.rc3
[PATCH 2/2] arm64: cpuidle: make arm_cpuidle_suspend() a bit more efficient
Currently, we check cpu_ops->cpu_suspend every time when entering a low-power idle state. But this check could be avoided in this hot path by moving it into arm_cpuidle_init() to reduce arm_cpuidle_suspend() overhead a bit. Signed-off-by: Jisheng Zhang --- arch/arm64/kernel/cpuidle.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c index bd57c59..e11857f 100644 --- a/arch/arm64/kernel/cpuidle.c +++ b/arch/arm64/kernel/cpuidle.c @@ -19,7 +19,8 @@ int __init arm_cpuidle_init(unsigned int cpu) { int ret = -EOPNOTSUPP; - if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_init_idle) + if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_suspend && + cpu_ops[cpu]->cpu_init_idle) ret = cpu_ops[cpu]->cpu_init_idle(cpu); return ret; @@ -36,10 +37,5 @@ int arm_cpuidle_suspend(int index) { int cpu = smp_processor_id(); - /* -* If suspend has not been initialized, cpu_suspend call fails early. -*/ - if (!cpu_ops[cpu]->cpu_suspend) - return -EOPNOTSUPP; return cpu_ops[cpu]->cpu_suspend(index); } -- 2.8.0.rc3
[PATCH 1/2] arm64: cpuidle: remove cpu_ops check from arm_cpuidle_suspend()
If cpu_ops has not been registered, arm_cpuidle_init() will return -EOPNOTSUPP, so arm_cpuidle_suspend() will never have chance to run. In other word, the cpu_ops check can be avoid. Signed-off-by: Jisheng Zhang --- arch/arm64/kernel/cpuidle.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c index 9047cab6..bd57c59 100644 --- a/arch/arm64/kernel/cpuidle.c +++ b/arch/arm64/kernel/cpuidle.c @@ -37,10 +37,9 @@ int arm_cpuidle_suspend(int index) int cpu = smp_processor_id(); /* -* If cpu_ops have not been registered or suspend -* has not been initialized, cpu_suspend call fails early. +* If suspend has not been initialized, cpu_suspend call fails early. */ - if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_suspend) + if (!cpu_ops[cpu]->cpu_suspend) return -EOPNOTSUPP; return cpu_ops[cpu]->cpu_suspend(index); } -- 2.8.0.rc3
[PATCH 0/2] arm64: cpuidle: make arm_cpuidle_suspend() more efficient
This series is to improve the arm_cpuidle_suspend() a bit by removing/moving out checks from this hot path. Jisheng Zhang (2): arm64: cpuidle: remove cpu_ops check from arm_cpuidle_suspend() arm64: cpuidle: make arm_cpuidle_suspend() a bit more efficient arch/arm64/kernel/cpuidle.c | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) -- 2.8.0.rc3
[PATCH 0/2] arm64: cpuidle: make arm_cpuidle_suspend() more efficient
This series is to improve the arm_cpuidle_suspend() a bit by removing/moving out checks from this hot path. Jisheng Zhang (2): arm64: cpuidle: remove cpu_ops check from arm_cpuidle_suspend() arm64: cpuidle: make arm_cpuidle_suspend() a bit more efficient arch/arm64/kernel/cpuidle.c | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) -- 2.8.0.rc3
[PATCH] cpuidle: arm: make enter idle operation a bit more efficient
Currently, entering idle need to check the idx every time to choose the real entering idle routine. But this check could be avoided by pointing the idle enter function pointer of each idle states to the routines suitable for each states directly. Signed-off-by: Jisheng Zhang--- drivers/cpuidle/cpuidle-arm.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c index 545069d..48a620f 100644 --- a/drivers/cpuidle/cpuidle-arm.c +++ b/drivers/cpuidle/cpuidle-arm.c @@ -23,6 +23,13 @@ #include "dt_idle_states.h" +static int arm_enter_wfi_state(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int idx) +{ + cpu_do_idle(); + return 0; +} + /* * arm_enter_idle_state - Programs CPU to enter the specified state * @@ -38,11 +45,6 @@ static int arm_enter_idle_state(struct cpuidle_device *dev, { int ret; - if (!idx) { - cpu_do_idle(); - return idx; - } - ret = cpu_pm_enter(); if (!ret) { /* @@ -69,7 +71,7 @@ static struct cpuidle_driver arm_idle_driver = { * handler for idle state index 0. */ .states[0] = { - .enter = arm_enter_idle_state, + .enter = arm_enter_wfi_state, .exit_latency = 1, .target_residency = 1, .power_usage= UINT_MAX, -- 2.8.0.rc3
[PATCH] cpuidle: arm: make enter idle operation a bit more efficient
Currently, entering idle need to check the idx every time to choose the real entering idle routine. But this check could be avoided by pointing the idle enter function pointer of each idle states to the routines suitable for each states directly. Signed-off-by: Jisheng Zhang --- drivers/cpuidle/cpuidle-arm.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c index 545069d..48a620f 100644 --- a/drivers/cpuidle/cpuidle-arm.c +++ b/drivers/cpuidle/cpuidle-arm.c @@ -23,6 +23,13 @@ #include "dt_idle_states.h" +static int arm_enter_wfi_state(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int idx) +{ + cpu_do_idle(); + return 0; +} + /* * arm_enter_idle_state - Programs CPU to enter the specified state * @@ -38,11 +45,6 @@ static int arm_enter_idle_state(struct cpuidle_device *dev, { int ret; - if (!idx) { - cpu_do_idle(); - return idx; - } - ret = cpu_pm_enter(); if (!ret) { /* @@ -69,7 +71,7 @@ static struct cpuidle_driver arm_idle_driver = { * handler for idle state index 0. */ .states[0] = { - .enter = arm_enter_idle_state, + .enter = arm_enter_wfi_state, .exit_latency = 1, .target_residency = 1, .power_usage= UINT_MAX, -- 2.8.0.rc3
Re: Re: [PATCH v2 13/18] mm/compaction: support non-lru movable pagemigration
On Thu, Mar 24, 2016 at 05:26:50AM +0900, Gioh Kim wrote: >Hmmm... But, in failure case, is it safe to call putback_lru_page() for >them? >And, PageIsolated() would be left. Is it okay? It's not symmetric that >isolated page can be freed by decreasing ref count without calling >putback function. This should be clarified and documented. > >I agree Joonsoo's idea. > >Freeing isolated page out of putback() could be confused. If we makes such rule, subsystem cannot free the isolated pages until VM calls putback. I don't think it's a good idea. With it, every users should make own deferred page freeing logic which might be more error-prone and obstacle for using this interface. I want to make client free his pages whenever he want if possible. > >Every detail cannot be documented. And more documents mean less elegant >code. > >Is it possible to free isolated page in putback()? > >In move_to_new_page(), can we call a_ops->migratepage like following? > >move_to_new_page() > >{ > >mapping = page_mapping(page) > >if (!mapping) > >rc = migrate_page > >else if (mapping->a_ops->migratepage && IsolatePage(page)) > > rc = mapping->a_ops->migratepage > It's not a problem. The problem is that a page failed migration so VM will putback the page. But, between fail of migration and putback of isolated page, user can free the page. In this case, putback operation would be not called and pass the page in putback_lru_page. >else > >rc = fallback_migrate_page > >... > > return rc > >} > >I'm sorry that I couldn't review in detail because I forgot many >details. You're a human being, not Alphago. :) Thanks for the review, Gioh! > >[1][Kk8NwEH1.I.q95.FfPs-qw00] >[@from=gurugio=minchan%40kernel%2Eorg=%3C20160324052650%2EHM >%2Ee06t8Yn%40gurugio%2Ewwl1662%2Ehanmail%2Enet%3E] > > References > >1. mailto:guru...@hanmail.net
Re: Re: [PATCH v2 13/18] mm/compaction: support non-lru movable pagemigration
On Thu, Mar 24, 2016 at 05:26:50AM +0900, Gioh Kim wrote: >Hmmm... But, in failure case, is it safe to call putback_lru_page() for >them? >And, PageIsolated() would be left. Is it okay? It's not symmetric that >isolated page can be freed by decreasing ref count without calling >putback function. This should be clarified and documented. > >I agree Joonsoo's idea. > >Freeing isolated page out of putback() could be confused. If we makes such rule, subsystem cannot free the isolated pages until VM calls putback. I don't think it's a good idea. With it, every users should make own deferred page freeing logic which might be more error-prone and obstacle for using this interface. I want to make client free his pages whenever he want if possible. > >Every detail cannot be documented. And more documents mean less elegant >code. > >Is it possible to free isolated page in putback()? > >In move_to_new_page(), can we call a_ops->migratepage like following? > >move_to_new_page() > >{ > >mapping = page_mapping(page) > >if (!mapping) > >rc = migrate_page > >else if (mapping->a_ops->migratepage && IsolatePage(page)) > > rc = mapping->a_ops->migratepage > It's not a problem. The problem is that a page failed migration so VM will putback the page. But, between fail of migration and putback of isolated page, user can free the page. In this case, putback operation would be not called and pass the page in putback_lru_page. >else > >rc = fallback_migrate_page > >... > > return rc > >} > >I'm sorry that I couldn't review in detail because I forgot many >details. You're a human being, not Alphago. :) Thanks for the review, Gioh! > >[1][Kk8NwEH1.I.q95.FfPs-qw00] >[@from=gurugio=minchan%40kernel%2Eorg=%3C20160324052650%2EHM >%2Ee06t8Yn%40gurugio%2Ewwl1662%2Ehanmail%2Enet%3E] > > References > >1. mailto:guru...@hanmail.net
Re: net/sctp: stack-out-of-bounds in sctp_getsockopt
2016-03-24 1:38 GMT+08:00, Pablo Neira Ayuso: > On Thu, Mar 24, 2016 at 12:42:43AM +0800, Baozeng wrote: >> 2016-03-22 23:27 GMT+08:00 Eric Dumazet : >> > Untested patch would be : >> > >> > diff --git a/net/bridge/netfilter/ebtables.c >> > b/net/bridge/netfilter/ebtables.c >> > index 67b2e27999aa..fceb7354d169 100644 >> > --- a/net/bridge/netfilter/ebtables.c >> > +++ b/net/bridge/netfilter/ebtables.c >> > @@ -346,7 +346,7 @@ find_inlist_lock(struct list_head *head, const char >> > *name, const char *prefix, >> > { >> > return try_then_request_module( >> > find_inlist_lock_noload(head, name, error, >> > mutex), >> > - "%s%s", prefix, name); >> > + "%.*s%s", EBT_TABLE_MAXNAMELEN, prefix, name); >> > } >> > >> > static inline struct ebt_table * >> > >> > >> >> Thanks for your quick patch. I tested it but it still reproduce the >> bug. We should limit the length of the name, >> not the prefix. The following patch fixs it. > > Could you give a try to this patch? Thanks. > I tested with your patch. It fixs the bug. Thanks. -- Best Regards, Baozeng Ding
Re: net/sctp: stack-out-of-bounds in sctp_getsockopt
2016-03-24 1:38 GMT+08:00, Pablo Neira Ayuso : > On Thu, Mar 24, 2016 at 12:42:43AM +0800, Baozeng wrote: >> 2016-03-22 23:27 GMT+08:00 Eric Dumazet : >> > Untested patch would be : >> > >> > diff --git a/net/bridge/netfilter/ebtables.c >> > b/net/bridge/netfilter/ebtables.c >> > index 67b2e27999aa..fceb7354d169 100644 >> > --- a/net/bridge/netfilter/ebtables.c >> > +++ b/net/bridge/netfilter/ebtables.c >> > @@ -346,7 +346,7 @@ find_inlist_lock(struct list_head *head, const char >> > *name, const char *prefix, >> > { >> > return try_then_request_module( >> > find_inlist_lock_noload(head, name, error, >> > mutex), >> > - "%s%s", prefix, name); >> > + "%.*s%s", EBT_TABLE_MAXNAMELEN, prefix, name); >> > } >> > >> > static inline struct ebt_table * >> > >> > >> >> Thanks for your quick patch. I tested it but it still reproduce the >> bug. We should limit the length of the name, >> not the prefix. The following patch fixs it. > > Could you give a try to this patch? Thanks. > I tested with your patch. It fixs the bug. Thanks. -- Best Regards, Baozeng Ding
Re: [PATCH v2 13/18] mm/compaction: support non-lru movable page migration
On Wed, Mar 23, 2016 at 02:05:11PM +0900, Joonsoo Kim wrote: > On Tue, Mar 22, 2016 at 11:55:45PM +0900, Minchan Kim wrote: > > On Tue, Mar 22, 2016 at 02:50:37PM +0900, Joonsoo Kim wrote: > > > On Mon, Mar 21, 2016 at 03:31:02PM +0900, Minchan Kim wrote: > > > > We have allowed migration for only LRU pages until now and it was > > > > enough to make high-order pages. But recently, embedded system(e.g., > > > > webOS, android) uses lots of non-movable pages(e.g., zram, GPU memory) > > > > so we have seen several reports about troubles of small high-order > > > > allocation. For fixing the problem, there were several efforts > > > > (e,g,. enhance compaction algorithm, SLUB fallback to 0-order page, > > > > reserved memory, vmalloc and so on) but if there are lots of > > > > non-movable pages in system, their solutions are void in the long run. > > > > > > > > So, this patch is to support facility to change non-movable pages > > > > with movable. For the feature, this patch introduces functions related > > > > to migration to address_space_operations as well as some page flags. > > > > > > > > Basically, this patch supports two page-flags and two functions related > > > > to page migration. The flag and page->mapping stability are protected > > > > by PG_lock. > > > > > > > > PG_movable > > > > PG_isolated > > > > > > > > bool (*isolate_page) (struct page *, isolate_mode_t); > > > > void (*putback_page) (struct page *); > > > > > > > > Duty of subsystem want to make their pages as migratable are > > > > as follows: > > > > > > > > 1. It should register address_space to page->mapping then mark > > > > the page as PG_movable via __SetPageMovable. > > > > > > > > 2. It should mark the page as PG_isolated via SetPageIsolated > > > > if isolation is sucessful and return true. > > > > > > > > 3. If migration is successful, it should clear PG_isolated and > > > > PG_movable of the page for free preparation then release the > > > > reference of the page to free. > > > > > > > > 4. If migration fails, putback function of subsystem should > > > > clear PG_isolated via ClearPageIsolated. > > > > > > I think that this feature needs a separate document to describe > > > requirement of each step in more detail. For example, #1 can be > > > possible without holding a lock? I'm not sure because you lock > > > the page when implementing zsmalloc page migration in 15th patch. > > > > Yes, we needs PG_lock because install page->mapping and PG_movable > > should be atomic and PG_lock protects it. > > > > Better interface might be > > > > void __SetPageMovable(struct page *page, sruct address_space *mapping); > > > > > > > > #3 also need more explanation. Before release, we need to > > > unregister address_space. I guess that it needs to be done > > > in migratepage() but there is no explanation. > > > > Okay, we can unregister address_space in __ClearPageMovable. > > I will change it. > > > > > > > > > > > > > Cc: Vlastimil Babka> > > > Cc: Mel Gorman > > > > Cc: Hugh Dickins > > > > Cc: dri-de...@lists.freedesktop.org > > > > Cc: virtualizat...@lists.linux-foundation.org > > > > Signed-off-by: Gioh Kim > > > > Signed-off-by: Minchan Kim > > > > --- > > > > Documentation/filesystems/Locking | 4 + > > > > Documentation/filesystems/vfs.txt | 5 ++ > > > > fs/proc/page.c | 3 + > > > > include/linux/fs.h | 2 + > > > > include/linux/migrate.h| 2 + > > > > include/linux/page-flags.h | 29 > > > > include/uapi/linux/kernel-page-flags.h | 1 + > > > > mm/compaction.c| 14 +++- > > > > mm/migrate.c | 132 > > > > + > > > > 9 files changed, 177 insertions(+), 15 deletions(-) > > > > > > > > diff --git a/Documentation/filesystems/Locking > > > > b/Documentation/filesystems/Locking > > > > index 619af9bfdcb3..0bb79560abb3 100644 > > > > --- a/Documentation/filesystems/Locking > > > > +++ b/Documentation/filesystems/Locking > > > > @@ -195,7 +195,9 @@ unlocks and drops the reference. > > > > int (*releasepage) (struct page *, int); > > > > void (*freepage)(struct page *); > > > > int (*direct_IO)(struct kiocb *, struct iov_iter *iter, loff_t > > > > offset); > > > > + bool (*isolate_page) (struct page *, isolate_mode_t); > > > > int (*migratepage)(struct address_space *, struct page *, > > > > struct page *); > > > > + void (*putback_page) (struct page *); > > > > int (*launder_page)(struct page *); > > > > int (*is_partially_uptodate)(struct page *, unsigned long, > > > > unsigned long); > > > > int (*error_remove_page)(struct address_space *, struct page *); > > > > @@ -219,7 +221,9 @@ invalidatepage: yes > > > >
Re: [PATCH v2 13/18] mm/compaction: support non-lru movable page migration
On Wed, Mar 23, 2016 at 02:05:11PM +0900, Joonsoo Kim wrote: > On Tue, Mar 22, 2016 at 11:55:45PM +0900, Minchan Kim wrote: > > On Tue, Mar 22, 2016 at 02:50:37PM +0900, Joonsoo Kim wrote: > > > On Mon, Mar 21, 2016 at 03:31:02PM +0900, Minchan Kim wrote: > > > > We have allowed migration for only LRU pages until now and it was > > > > enough to make high-order pages. But recently, embedded system(e.g., > > > > webOS, android) uses lots of non-movable pages(e.g., zram, GPU memory) > > > > so we have seen several reports about troubles of small high-order > > > > allocation. For fixing the problem, there were several efforts > > > > (e,g,. enhance compaction algorithm, SLUB fallback to 0-order page, > > > > reserved memory, vmalloc and so on) but if there are lots of > > > > non-movable pages in system, their solutions are void in the long run. > > > > > > > > So, this patch is to support facility to change non-movable pages > > > > with movable. For the feature, this patch introduces functions related > > > > to migration to address_space_operations as well as some page flags. > > > > > > > > Basically, this patch supports two page-flags and two functions related > > > > to page migration. The flag and page->mapping stability are protected > > > > by PG_lock. > > > > > > > > PG_movable > > > > PG_isolated > > > > > > > > bool (*isolate_page) (struct page *, isolate_mode_t); > > > > void (*putback_page) (struct page *); > > > > > > > > Duty of subsystem want to make their pages as migratable are > > > > as follows: > > > > > > > > 1. It should register address_space to page->mapping then mark > > > > the page as PG_movable via __SetPageMovable. > > > > > > > > 2. It should mark the page as PG_isolated via SetPageIsolated > > > > if isolation is sucessful and return true. > > > > > > > > 3. If migration is successful, it should clear PG_isolated and > > > > PG_movable of the page for free preparation then release the > > > > reference of the page to free. > > > > > > > > 4. If migration fails, putback function of subsystem should > > > > clear PG_isolated via ClearPageIsolated. > > > > > > I think that this feature needs a separate document to describe > > > requirement of each step in more detail. For example, #1 can be > > > possible without holding a lock? I'm not sure because you lock > > > the page when implementing zsmalloc page migration in 15th patch. > > > > Yes, we needs PG_lock because install page->mapping and PG_movable > > should be atomic and PG_lock protects it. > > > > Better interface might be > > > > void __SetPageMovable(struct page *page, sruct address_space *mapping); > > > > > > > > #3 also need more explanation. Before release, we need to > > > unregister address_space. I guess that it needs to be done > > > in migratepage() but there is no explanation. > > > > Okay, we can unregister address_space in __ClearPageMovable. > > I will change it. > > > > > > > > > > > > > Cc: Vlastimil Babka > > > > Cc: Mel Gorman > > > > Cc: Hugh Dickins > > > > Cc: dri-de...@lists.freedesktop.org > > > > Cc: virtualizat...@lists.linux-foundation.org > > > > Signed-off-by: Gioh Kim > > > > Signed-off-by: Minchan Kim > > > > --- > > > > Documentation/filesystems/Locking | 4 + > > > > Documentation/filesystems/vfs.txt | 5 ++ > > > > fs/proc/page.c | 3 + > > > > include/linux/fs.h | 2 + > > > > include/linux/migrate.h| 2 + > > > > include/linux/page-flags.h | 29 > > > > include/uapi/linux/kernel-page-flags.h | 1 + > > > > mm/compaction.c| 14 +++- > > > > mm/migrate.c | 132 > > > > + > > > > 9 files changed, 177 insertions(+), 15 deletions(-) > > > > > > > > diff --git a/Documentation/filesystems/Locking > > > > b/Documentation/filesystems/Locking > > > > index 619af9bfdcb3..0bb79560abb3 100644 > > > > --- a/Documentation/filesystems/Locking > > > > +++ b/Documentation/filesystems/Locking > > > > @@ -195,7 +195,9 @@ unlocks and drops the reference. > > > > int (*releasepage) (struct page *, int); > > > > void (*freepage)(struct page *); > > > > int (*direct_IO)(struct kiocb *, struct iov_iter *iter, loff_t > > > > offset); > > > > + bool (*isolate_page) (struct page *, isolate_mode_t); > > > > int (*migratepage)(struct address_space *, struct page *, > > > > struct page *); > > > > + void (*putback_page) (struct page *); > > > > int (*launder_page)(struct page *); > > > > int (*is_partially_uptodate)(struct page *, unsigned long, > > > > unsigned long); > > > > int (*error_remove_page)(struct address_space *, struct page *); > > > > @@ -219,7 +221,9 @@ invalidatepage: yes > > > > releasepage: yes > > > > freepage: yes > > > > direct_IO: > > > >
[PATCH v5 01/21] PM / devfreq: exynos: Add generic exynos bus frequency driver
This patch adds the generic exynos bus frequency driver for AMBA AXI bus of sub-blocks in exynos SoC with DEVFREQ framework. The Samsung Exynos SoC have the common architecture for bus between DRAM and sub-blocks in SoC. This driver can support the generic bus frequency driver for Exynos SoCs. In devicetree, Each bus block has a bus clock, regulator, operation-point and devfreq-event devices which measure the utilization of each bus block. Signed-off-by: Chanwoo Choi--- drivers/devfreq/Kconfig | 15 ++ drivers/devfreq/Makefile | 1 + drivers/devfreq/exynos-bus.c | 443 +++ 3 files changed, 459 insertions(+) create mode 100644 drivers/devfreq/exynos-bus.c diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 64281bb2f650..55ec774f794c 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -66,6 +66,21 @@ config DEVFREQ_GOV_USERSPACE comment "DEVFREQ Drivers" +config ARM_EXYNOS_BUS_DEVFREQ + bool "ARM EXYNOS Generic Memory Bus DEVFREQ Driver" + depends on ARCH_EXYNOS + select DEVFREQ_GOV_SIMPLE_ONDEMAND + select DEVFREQ_EVENT_EXYNOS_PPMU + select PM_DEVFREQ_EVENT + select PM_OPP + help + This adds the common DEVFREQ driver for Exynos Memory bus. Exynos + Memory bus has one more group of memory bus (e.g, MIF and INT block). + Each memory bus group could contain many memoby bus block. It reads + PPMU counters of memory controllers by using DEVFREQ-event device + and adjusts the operating frequencies and voltages with OPP support. + This does not yet operate with optimal voltages. + config ARM_EXYNOS4_BUS_DEVFREQ bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver" depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile index 5134f9ee983d..8af8aaf922a8 100644 --- a/drivers/devfreq/Makefile +++ b/drivers/devfreq/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE) += governor_powersave.o obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)+= governor_userspace.o # DEVFREQ Drivers +obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos/ obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ) += exynos/ obj-$(CONFIG_ARM_TEGRA_DEVFREQ)+= tegra-devfreq.o diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c new file mode 100644 index ..f79963187fa1 --- /dev/null +++ b/drivers/devfreq/exynos-bus.c @@ -0,0 +1,443 @@ +/* + * Generic Exynos Bus frequency driver with DEVFREQ Framework + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Author : Chanwoo Choi + * + * This driver support Exynos Bus frequency feature by using + * DEVFREQ framework and is based on drivers/devfreq/exynos/exynos4_bus.c. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_SATURATION_RATIO 40 +#define DEFAULT_VOLTAGE_TOLERANCE 2 + +struct exynos_bus { + struct device *dev; + + struct devfreq *devfreq; + struct devfreq_event_dev **edev; + unsigned int edev_count; + struct mutex lock; + + struct dev_pm_opp *curr_opp; + + struct regulator *regulator; + struct clk *clk; + unsigned int voltage_tolerance; + unsigned int ratio; +}; + +/* + * Control the devfreq-event device to get the current state of bus + */ +#define exynos_bus_ops_edev(ops) \ +static int exynos_bus_##ops(struct exynos_bus *bus)\ +{ \ + int i, ret; \ + \ + for (i = 0; i < bus->edev_count; i++) { \ + if (!bus->edev[i]) \ + continue; \ + ret = devfreq_event_##ops(bus->edev[i]);\ + if (ret < 0)\ + return ret; \ + } \ + \ + return 0; \ +} +exynos_bus_ops_edev(enable_edev); +exynos_bus_ops_edev(disable_edev); +exynos_bus_ops_edev(set_event); + +static int exynos_bus_get_event(struct exynos_bus *bus, + struct devfreq_event_data *edata) +{ + struct
[PATCH v5 01/21] PM / devfreq: exynos: Add generic exynos bus frequency driver
This patch adds the generic exynos bus frequency driver for AMBA AXI bus of sub-blocks in exynos SoC with DEVFREQ framework. The Samsung Exynos SoC have the common architecture for bus between DRAM and sub-blocks in SoC. This driver can support the generic bus frequency driver for Exynos SoCs. In devicetree, Each bus block has a bus clock, regulator, operation-point and devfreq-event devices which measure the utilization of each bus block. Signed-off-by: Chanwoo Choi --- drivers/devfreq/Kconfig | 15 ++ drivers/devfreq/Makefile | 1 + drivers/devfreq/exynos-bus.c | 443 +++ 3 files changed, 459 insertions(+) create mode 100644 drivers/devfreq/exynos-bus.c diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 64281bb2f650..55ec774f794c 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -66,6 +66,21 @@ config DEVFREQ_GOV_USERSPACE comment "DEVFREQ Drivers" +config ARM_EXYNOS_BUS_DEVFREQ + bool "ARM EXYNOS Generic Memory Bus DEVFREQ Driver" + depends on ARCH_EXYNOS + select DEVFREQ_GOV_SIMPLE_ONDEMAND + select DEVFREQ_EVENT_EXYNOS_PPMU + select PM_DEVFREQ_EVENT + select PM_OPP + help + This adds the common DEVFREQ driver for Exynos Memory bus. Exynos + Memory bus has one more group of memory bus (e.g, MIF and INT block). + Each memory bus group could contain many memoby bus block. It reads + PPMU counters of memory controllers by using DEVFREQ-event device + and adjusts the operating frequencies and voltages with OPP support. + This does not yet operate with optimal voltages. + config ARM_EXYNOS4_BUS_DEVFREQ bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver" depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile index 5134f9ee983d..8af8aaf922a8 100644 --- a/drivers/devfreq/Makefile +++ b/drivers/devfreq/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE) += governor_powersave.o obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)+= governor_userspace.o # DEVFREQ Drivers +obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos/ obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ) += exynos/ obj-$(CONFIG_ARM_TEGRA_DEVFREQ)+= tegra-devfreq.o diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c new file mode 100644 index ..f79963187fa1 --- /dev/null +++ b/drivers/devfreq/exynos-bus.c @@ -0,0 +1,443 @@ +/* + * Generic Exynos Bus frequency driver with DEVFREQ Framework + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Author : Chanwoo Choi + * + * This driver support Exynos Bus frequency feature by using + * DEVFREQ framework and is based on drivers/devfreq/exynos/exynos4_bus.c. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_SATURATION_RATIO 40 +#define DEFAULT_VOLTAGE_TOLERANCE 2 + +struct exynos_bus { + struct device *dev; + + struct devfreq *devfreq; + struct devfreq_event_dev **edev; + unsigned int edev_count; + struct mutex lock; + + struct dev_pm_opp *curr_opp; + + struct regulator *regulator; + struct clk *clk; + unsigned int voltage_tolerance; + unsigned int ratio; +}; + +/* + * Control the devfreq-event device to get the current state of bus + */ +#define exynos_bus_ops_edev(ops) \ +static int exynos_bus_##ops(struct exynos_bus *bus)\ +{ \ + int i, ret; \ + \ + for (i = 0; i < bus->edev_count; i++) { \ + if (!bus->edev[i]) \ + continue; \ + ret = devfreq_event_##ops(bus->edev[i]);\ + if (ret < 0)\ + return ret; \ + } \ + \ + return 0; \ +} +exynos_bus_ops_edev(enable_edev); +exynos_bus_ops_edev(disable_edev); +exynos_bus_ops_edev(set_event); + +static int exynos_bus_get_event(struct exynos_bus *bus, + struct devfreq_event_data *edata) +{ + struct devfreq_event_data event_data; + unsigned
[PATCH v5 04/21] PM / devfreq: Add new DEVFREQ_TRANSITION_NOTIFIER notifier
This patch adds the new DEVFREQ_TRANSITION_NOTIFIER notifier to send the notification when the frequency of device is changed. This notifier has two state as following: - DEVFREQ_PRECHANGE : Notify it before chaning the frequency of device - DEVFREQ_POSTCHANGE : Notify it after changed the frequency of device And this patch adds the resourced-managed function to release the resource automatically when error happen. Signed-off-by: Chanwoo Choi--- drivers/devfreq/devfreq.c | 163 +- include/linux/devfreq.h | 58 - 2 files changed, 219 insertions(+), 2 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 20a9422c2552..1d6c803804d5 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -189,6 +189,29 @@ static struct devfreq_governor *find_devfreq_governor(const char *name) return ERR_PTR(-ENODEV); } +static int devfreq_notify_transition(struct devfreq *devfreq, + struct devfreq_freqs *freqs, unsigned int state) +{ + if (!devfreq) + return -EINVAL; + + switch (state) { + case DEVFREQ_PRECHANGE: + srcu_notifier_call_chain(>transition_notifier_list, + DEVFREQ_PRECHANGE, freqs); + break; + + case DEVFREQ_POSTCHANGE: + srcu_notifier_call_chain(>transition_notifier_list, + DEVFREQ_POSTCHANGE, freqs); + break; + default: + return -EINVAL; + } + + return 0; +} + /* Load monitoring helper functions for governors use */ /** @@ -200,7 +223,8 @@ static struct devfreq_governor *find_devfreq_governor(const char *name) */ int update_devfreq(struct devfreq *devfreq) { - unsigned long freq; + struct devfreq_freqs freqs; + unsigned long freq, cur_freq; int err = 0; u32 flags = 0; @@ -234,10 +258,22 @@ int update_devfreq(struct devfreq *devfreq) flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */ } + if (devfreq->profile->get_cur_freq) + devfreq->profile->get_cur_freq(devfreq->dev.parent, _freq); + else + cur_freq = devfreq->previous_freq; + + freqs.old = cur_freq; + freqs.new = freq; + devfreq_notify_transition(devfreq, , DEVFREQ_PRECHANGE); + err = devfreq->profile->target(devfreq->dev.parent, , flags); if (err) return err; + freqs.new = freq; + devfreq_notify_transition(devfreq, , DEVFREQ_POSTCHANGE); + if (devfreq->profile->freq_table) if (devfreq_update_status(devfreq, freq)) dev_err(>dev, @@ -542,6 +578,8 @@ struct devfreq *devfreq_add_device(struct device *dev, goto err_out; } + srcu_init_notifier_head(>transition_notifier_list); + mutex_unlock(>lock); mutex_lock(_list_lock); @@ -1310,6 +1348,129 @@ void devm_devfreq_unregister_opp_notifier(struct device *dev, } EXPORT_SYMBOL(devm_devfreq_unregister_opp_notifier); +/** + * devfreq_register_notifier() - Register a driver with devfreq + * @devfreq: The devfreq object. + * @nb:The notifier block to register. + * @list: DEVFREQ_TRANSITION_NOTIFIER. + */ +int devfreq_register_notifier(struct devfreq *devfreq, + struct notifier_block *nb, + unsigned int list) +{ + int ret = 0; + + if (!devfreq) + return -EINVAL; + + switch (list) { + case DEVFREQ_TRANSITION_NOTIFIER: + ret = srcu_notifier_chain_register( + >transition_notifier_list, nb); + break; + default: + ret = -EINVAL; + } + + return ret; +} +EXPORT_SYMBOL(devfreq_register_notifier); + +/* + * devfreq_unregister_notifier() - Unregister a driver with devfreq + * @devfreq: The devfreq object. + * @nb:The notifier block to be unregistered. + * @list: DEVFREQ_TRANSITION_NOTIFIER. + */ +int devfreq_unregister_notifier(struct devfreq *devfreq, + struct notifier_block *nb, + unsigned int list) +{ + int ret = 0; + + if (!devfreq) + return -EINVAL; + + switch (list) { + case DEVFREQ_TRANSITION_NOTIFIER: + ret = srcu_notifier_chain_unregister( + >transition_notifier_list, nb); + break; + default: + ret = -EINVAL; + } + + return ret; +} +EXPORT_SYMBOL(devfreq_unregister_notifier); + +struct devfreq_notifier_devres { + struct devfreq *devfreq; + struct notifier_block *nb; + unsigned int list; +}; + +static void devm_devfreq_notifier_release(struct device *dev, void *res) +{ +
[PATCH v5 04/21] PM / devfreq: Add new DEVFREQ_TRANSITION_NOTIFIER notifier
This patch adds the new DEVFREQ_TRANSITION_NOTIFIER notifier to send the notification when the frequency of device is changed. This notifier has two state as following: - DEVFREQ_PRECHANGE : Notify it before chaning the frequency of device - DEVFREQ_POSTCHANGE : Notify it after changed the frequency of device And this patch adds the resourced-managed function to release the resource automatically when error happen. Signed-off-by: Chanwoo Choi --- drivers/devfreq/devfreq.c | 163 +- include/linux/devfreq.h | 58 - 2 files changed, 219 insertions(+), 2 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 20a9422c2552..1d6c803804d5 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -189,6 +189,29 @@ static struct devfreq_governor *find_devfreq_governor(const char *name) return ERR_PTR(-ENODEV); } +static int devfreq_notify_transition(struct devfreq *devfreq, + struct devfreq_freqs *freqs, unsigned int state) +{ + if (!devfreq) + return -EINVAL; + + switch (state) { + case DEVFREQ_PRECHANGE: + srcu_notifier_call_chain(>transition_notifier_list, + DEVFREQ_PRECHANGE, freqs); + break; + + case DEVFREQ_POSTCHANGE: + srcu_notifier_call_chain(>transition_notifier_list, + DEVFREQ_POSTCHANGE, freqs); + break; + default: + return -EINVAL; + } + + return 0; +} + /* Load monitoring helper functions for governors use */ /** @@ -200,7 +223,8 @@ static struct devfreq_governor *find_devfreq_governor(const char *name) */ int update_devfreq(struct devfreq *devfreq) { - unsigned long freq; + struct devfreq_freqs freqs; + unsigned long freq, cur_freq; int err = 0; u32 flags = 0; @@ -234,10 +258,22 @@ int update_devfreq(struct devfreq *devfreq) flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */ } + if (devfreq->profile->get_cur_freq) + devfreq->profile->get_cur_freq(devfreq->dev.parent, _freq); + else + cur_freq = devfreq->previous_freq; + + freqs.old = cur_freq; + freqs.new = freq; + devfreq_notify_transition(devfreq, , DEVFREQ_PRECHANGE); + err = devfreq->profile->target(devfreq->dev.parent, , flags); if (err) return err; + freqs.new = freq; + devfreq_notify_transition(devfreq, , DEVFREQ_POSTCHANGE); + if (devfreq->profile->freq_table) if (devfreq_update_status(devfreq, freq)) dev_err(>dev, @@ -542,6 +578,8 @@ struct devfreq *devfreq_add_device(struct device *dev, goto err_out; } + srcu_init_notifier_head(>transition_notifier_list); + mutex_unlock(>lock); mutex_lock(_list_lock); @@ -1310,6 +1348,129 @@ void devm_devfreq_unregister_opp_notifier(struct device *dev, } EXPORT_SYMBOL(devm_devfreq_unregister_opp_notifier); +/** + * devfreq_register_notifier() - Register a driver with devfreq + * @devfreq: The devfreq object. + * @nb:The notifier block to register. + * @list: DEVFREQ_TRANSITION_NOTIFIER. + */ +int devfreq_register_notifier(struct devfreq *devfreq, + struct notifier_block *nb, + unsigned int list) +{ + int ret = 0; + + if (!devfreq) + return -EINVAL; + + switch (list) { + case DEVFREQ_TRANSITION_NOTIFIER: + ret = srcu_notifier_chain_register( + >transition_notifier_list, nb); + break; + default: + ret = -EINVAL; + } + + return ret; +} +EXPORT_SYMBOL(devfreq_register_notifier); + +/* + * devfreq_unregister_notifier() - Unregister a driver with devfreq + * @devfreq: The devfreq object. + * @nb:The notifier block to be unregistered. + * @list: DEVFREQ_TRANSITION_NOTIFIER. + */ +int devfreq_unregister_notifier(struct devfreq *devfreq, + struct notifier_block *nb, + unsigned int list) +{ + int ret = 0; + + if (!devfreq) + return -EINVAL; + + switch (list) { + case DEVFREQ_TRANSITION_NOTIFIER: + ret = srcu_notifier_chain_unregister( + >transition_notifier_list, nb); + break; + default: + ret = -EINVAL; + } + + return ret; +} +EXPORT_SYMBOL(devfreq_unregister_notifier); + +struct devfreq_notifier_devres { + struct devfreq *devfreq; + struct notifier_block *nb; + unsigned int list; +}; + +static void devm_devfreq_notifier_release(struct device *dev, void *res) +{ + struct
[PATCH v5 09/21] PM / devfreq: exynos: Add the detailed correlation between sub-blocks and power line
This patch adds the detailed corrleation between sub-blocks and power line for Exynos3250, Exynos4210 and Exynos4x12. Signed-off-by: Chanwoo Choi--- .../devicetree/bindings/devfreq/exynos-bus.txt | 51 ++ 1 file changed, 51 insertions(+) diff --git a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt index 03f13d38f1a1..b098fa2ba5d4 100644 --- a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt +++ b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt @@ -53,6 +53,57 @@ Optional properties only for parent bus device: - exynos,voltage-tolerance: the percentage value for bus voltage tolerance which is used to calculate the max voltage. +Detailed correlation between sub-blocks and power line according to Exynos SoC: +- In case of Exynos3250, there are two power line as following: + VDD_MIF |--- DMC + + VDD_INT |--- LEFTBUS (parent device) + |--- PERIL + |--- MFC + |--- G3D + |--- RIGHTBUS + |--- PERIR + |--- FSYS + |--- LCD0 + |--- PERIR + |--- ISP + |--- CAM + +- In case of Exynos4210, there is one power line as following: + VDD_INT |--- DMC (parent device) + |--- LEFTBUS + |--- PERIL + |--- MFC(L) + |--- G3D + |--- TV + |--- LCD0 + |--- RIGHTBUS + |--- PERIR + |--- MFC(R) + |--- CAM + |--- FSYS + |--- GPS + |--- LCD0 + |--- LCD1 + +- In case of Exynos4x12, there are two power line as following: + VDD_MIF |--- DMC + + VDD_INT |--- LEFTBUS (parent device) + |--- PERIL + |--- MFC(L) + |--- G3D + |--- TV + |--- IMAGE + |--- RIGHTBUS + |--- PERIR + |--- MFC(R) + |--- CAM + |--- FSYS + |--- GPS + |--- LCD0 + |--- ISP + Example1: Show the AXI buses of Exynos3250 SoC. Exynos3250 divides the buses to power line (regulator). The MIF (Memory Interface) AXI bus is used to -- 1.9.1
[PATCH v5 05/21] PM / devfreq: Add governer type with unique number
This patch just adds the governor type to identify them by using the defined constant. Signed-off-by: Chanwoo Choi--- drivers/devfreq/governor.h| 6 ++ drivers/devfreq/governor_performance.c| 1 + drivers/devfreq/governor_powersave.c | 1 + drivers/devfreq/governor_simpleondemand.c | 1 + drivers/devfreq/governor_userspace.c | 1 + include/linux/devfreq.h | 2 ++ 6 files changed, 12 insertions(+) diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h index fad7d6321978..cf19b923c362 100644 --- a/drivers/devfreq/governor.h +++ b/drivers/devfreq/governor.h @@ -18,6 +18,12 @@ #define to_devfreq(DEV)container_of((DEV), struct devfreq, dev) +/* Devfreq governor type */ +#define DEVFREQ_GOV_ONDEMAND 0x1 +#define DEVFREQ_GOV_PERFORMANCE0x2 +#define DEVFREQ_GOV_POWERSAVE 0x3 +#define DEVFREQ_GOV_USERSPACE 0x4 + /* Devfreq events */ #define DEVFREQ_GOV_START 0x1 #define DEVFREQ_GOV_STOP 0x2 diff --git a/drivers/devfreq/governor_performance.c b/drivers/devfreq/governor_performance.c index c72f942f30a8..594d8ecb13fb 100644 --- a/drivers/devfreq/governor_performance.c +++ b/drivers/devfreq/governor_performance.c @@ -43,6 +43,7 @@ static int devfreq_performance_handler(struct devfreq *devfreq, static struct devfreq_governor devfreq_performance = { .name = "performance", + .type = DEVFREQ_GOV_PERFORMANCE, .get_target_freq = devfreq_performance_func, .event_handler = devfreq_performance_handler, }; diff --git a/drivers/devfreq/governor_powersave.c b/drivers/devfreq/governor_powersave.c index 0c6bed567e6d..e2817e1f2a31 100644 --- a/drivers/devfreq/governor_powersave.c +++ b/drivers/devfreq/governor_powersave.c @@ -40,6 +40,7 @@ static int devfreq_powersave_handler(struct devfreq *devfreq, static struct devfreq_governor devfreq_powersave = { .name = "powersave", + .type = DEVFREQ_GOV_POWERSAVE, .get_target_freq = devfreq_powersave_func, .event_handler = devfreq_powersave_handler, }; diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index ae72ba5e78df..b905a535d486 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -126,6 +126,7 @@ static int devfreq_simple_ondemand_handler(struct devfreq *devfreq, static struct devfreq_governor devfreq_simple_ondemand = { .name = "simple_ondemand", + .type = DEVFREQ_GOV_ONDEMAND, .get_target_freq = devfreq_simple_ondemand_func, .event_handler = devfreq_simple_ondemand_handler, }; diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c index 35de6e83c1fe..c78ab78a5220 100644 --- a/drivers/devfreq/governor_userspace.c +++ b/drivers/devfreq/governor_userspace.c @@ -138,6 +138,7 @@ static int devfreq_userspace_handler(struct devfreq *devfreq, static struct devfreq_governor devfreq_userspace = { .name = "userspace", + .type = DEVFREQ_GOV_USERSPACE, .get_target_freq = devfreq_userspace_func, .event_handler = devfreq_userspace_handler, }; diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 152ea342529c..9baf45f661ad 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -104,6 +104,7 @@ struct devfreq_dev_profile { * struct devfreq_governor - Devfreq policy governor * @node: list node - contains registered devfreq governors * @name: Governor's name + * @type: Governor's type * @get_target_freq: Returns desired operating frequency for the device. * Basically, get_target_freq will run * devfreq_dev_profile.get_dev_status() to get the @@ -121,6 +122,7 @@ struct devfreq_governor { struct list_head node; const char name[DEVFREQ_NAME_LEN]; + const int type; int (*get_target_freq)(struct devfreq *this, unsigned long *freq); int (*event_handler)(struct devfreq *devfreq, unsigned int event, void *data); -- 1.9.1
Re: [linux-sunxi] [PATCH v3 08/19] ARM: sun5i: Add DRAM gates
On Thu, Mar 24, 2016 at 12:38 AM, Maxime Ripardwrote: > The DRAM gates control whether the image / display devices on the SoC have > access to the DRAM clock or not. > > Enable it. > > Signed-off-by: Maxime Ripard Acked-by: Chen-Yu Tsai I assume you'll add another version for A10s, or move the whole thing to sun5i.dtsi later?
[PATCH v5 09/21] PM / devfreq: exynos: Add the detailed correlation between sub-blocks and power line
This patch adds the detailed corrleation between sub-blocks and power line for Exynos3250, Exynos4210 and Exynos4x12. Signed-off-by: Chanwoo Choi --- .../devicetree/bindings/devfreq/exynos-bus.txt | 51 ++ 1 file changed, 51 insertions(+) diff --git a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt index 03f13d38f1a1..b098fa2ba5d4 100644 --- a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt +++ b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt @@ -53,6 +53,57 @@ Optional properties only for parent bus device: - exynos,voltage-tolerance: the percentage value for bus voltage tolerance which is used to calculate the max voltage. +Detailed correlation between sub-blocks and power line according to Exynos SoC: +- In case of Exynos3250, there are two power line as following: + VDD_MIF |--- DMC + + VDD_INT |--- LEFTBUS (parent device) + |--- PERIL + |--- MFC + |--- G3D + |--- RIGHTBUS + |--- PERIR + |--- FSYS + |--- LCD0 + |--- PERIR + |--- ISP + |--- CAM + +- In case of Exynos4210, there is one power line as following: + VDD_INT |--- DMC (parent device) + |--- LEFTBUS + |--- PERIL + |--- MFC(L) + |--- G3D + |--- TV + |--- LCD0 + |--- RIGHTBUS + |--- PERIR + |--- MFC(R) + |--- CAM + |--- FSYS + |--- GPS + |--- LCD0 + |--- LCD1 + +- In case of Exynos4x12, there are two power line as following: + VDD_MIF |--- DMC + + VDD_INT |--- LEFTBUS (parent device) + |--- PERIL + |--- MFC(L) + |--- G3D + |--- TV + |--- IMAGE + |--- RIGHTBUS + |--- PERIR + |--- MFC(R) + |--- CAM + |--- FSYS + |--- GPS + |--- LCD0 + |--- ISP + Example1: Show the AXI buses of Exynos3250 SoC. Exynos3250 divides the buses to power line (regulator). The MIF (Memory Interface) AXI bus is used to -- 1.9.1
[PATCH v5 05/21] PM / devfreq: Add governer type with unique number
This patch just adds the governor type to identify them by using the defined constant. Signed-off-by: Chanwoo Choi --- drivers/devfreq/governor.h| 6 ++ drivers/devfreq/governor_performance.c| 1 + drivers/devfreq/governor_powersave.c | 1 + drivers/devfreq/governor_simpleondemand.c | 1 + drivers/devfreq/governor_userspace.c | 1 + include/linux/devfreq.h | 2 ++ 6 files changed, 12 insertions(+) diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h index fad7d6321978..cf19b923c362 100644 --- a/drivers/devfreq/governor.h +++ b/drivers/devfreq/governor.h @@ -18,6 +18,12 @@ #define to_devfreq(DEV)container_of((DEV), struct devfreq, dev) +/* Devfreq governor type */ +#define DEVFREQ_GOV_ONDEMAND 0x1 +#define DEVFREQ_GOV_PERFORMANCE0x2 +#define DEVFREQ_GOV_POWERSAVE 0x3 +#define DEVFREQ_GOV_USERSPACE 0x4 + /* Devfreq events */ #define DEVFREQ_GOV_START 0x1 #define DEVFREQ_GOV_STOP 0x2 diff --git a/drivers/devfreq/governor_performance.c b/drivers/devfreq/governor_performance.c index c72f942f30a8..594d8ecb13fb 100644 --- a/drivers/devfreq/governor_performance.c +++ b/drivers/devfreq/governor_performance.c @@ -43,6 +43,7 @@ static int devfreq_performance_handler(struct devfreq *devfreq, static struct devfreq_governor devfreq_performance = { .name = "performance", + .type = DEVFREQ_GOV_PERFORMANCE, .get_target_freq = devfreq_performance_func, .event_handler = devfreq_performance_handler, }; diff --git a/drivers/devfreq/governor_powersave.c b/drivers/devfreq/governor_powersave.c index 0c6bed567e6d..e2817e1f2a31 100644 --- a/drivers/devfreq/governor_powersave.c +++ b/drivers/devfreq/governor_powersave.c @@ -40,6 +40,7 @@ static int devfreq_powersave_handler(struct devfreq *devfreq, static struct devfreq_governor devfreq_powersave = { .name = "powersave", + .type = DEVFREQ_GOV_POWERSAVE, .get_target_freq = devfreq_powersave_func, .event_handler = devfreq_powersave_handler, }; diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index ae72ba5e78df..b905a535d486 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -126,6 +126,7 @@ static int devfreq_simple_ondemand_handler(struct devfreq *devfreq, static struct devfreq_governor devfreq_simple_ondemand = { .name = "simple_ondemand", + .type = DEVFREQ_GOV_ONDEMAND, .get_target_freq = devfreq_simple_ondemand_func, .event_handler = devfreq_simple_ondemand_handler, }; diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c index 35de6e83c1fe..c78ab78a5220 100644 --- a/drivers/devfreq/governor_userspace.c +++ b/drivers/devfreq/governor_userspace.c @@ -138,6 +138,7 @@ static int devfreq_userspace_handler(struct devfreq *devfreq, static struct devfreq_governor devfreq_userspace = { .name = "userspace", + .type = DEVFREQ_GOV_USERSPACE, .get_target_freq = devfreq_userspace_func, .event_handler = devfreq_userspace_handler, }; diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 152ea342529c..9baf45f661ad 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -104,6 +104,7 @@ struct devfreq_dev_profile { * struct devfreq_governor - Devfreq policy governor * @node: list node - contains registered devfreq governors * @name: Governor's name + * @type: Governor's type * @get_target_freq: Returns desired operating frequency for the device. * Basically, get_target_freq will run * devfreq_dev_profile.get_dev_status() to get the @@ -121,6 +122,7 @@ struct devfreq_governor { struct list_head node; const char name[DEVFREQ_NAME_LEN]; + const int type; int (*get_target_freq)(struct devfreq *this, unsigned long *freq); int (*event_handler)(struct devfreq *devfreq, unsigned int event, void *data); -- 1.9.1
Re: [linux-sunxi] [PATCH v3 08/19] ARM: sun5i: Add DRAM gates
On Thu, Mar 24, 2016 at 12:38 AM, Maxime Ripard wrote: > The DRAM gates control whether the image / display devices on the SoC have > access to the DRAM clock or not. > > Enable it. > > Signed-off-by: Maxime Ripard Acked-by: Chen-Yu Tsai I assume you'll add another version for A10s, or move the whole thing to sun5i.dtsi later?
[PATCH v5 11/21] MAINTAINERS: Add samsung bus frequency driver entry
This patch adds the 'BUS FREQUENCY DRIVER FOR SAMSUNG EXYNOS' entry to review the patches as maintainer. Patches will be picked up by DEVFREQ maintainer on devfreq git repository. Signed-off-by: Chanwoo Choi--- MAINTAINERS | 9 + 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 32bafda47c2f..9040f6a89ffe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3539,6 +3539,15 @@ F: drivers/devfreq/devfreq-event.c F: include/linux/devfreq-event.h F: Documentation/devicetree/bindings/devfreq/event/ +BUS FREQUENCY DRIVER FOR SAMSUNG EXYNOS +M: Chanwoo Choi +L: linux...@vger.kernel.org +L: linux-samsung-...@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git +S: Maintained +F: drivers/devfreq/exynos-bus.c +F: Documentation/devicetree/bindings/devfreq/exynos-bus.txt + DEVICE NUMBER REGISTRY M: Torben Mathiasen W: http://lanana.org/docs/device-list/index.html -- 1.9.1
[PATCH v5 11/21] MAINTAINERS: Add samsung bus frequency driver entry
This patch adds the 'BUS FREQUENCY DRIVER FOR SAMSUNG EXYNOS' entry to review the patches as maintainer. Patches will be picked up by DEVFREQ maintainer on devfreq git repository. Signed-off-by: Chanwoo Choi --- MAINTAINERS | 9 + 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 32bafda47c2f..9040f6a89ffe 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3539,6 +3539,15 @@ F: drivers/devfreq/devfreq-event.c F: include/linux/devfreq-event.h F: Documentation/devicetree/bindings/devfreq/event/ +BUS FREQUENCY DRIVER FOR SAMSUNG EXYNOS +M: Chanwoo Choi +L: linux...@vger.kernel.org +L: linux-samsung-...@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git +S: Maintained +F: drivers/devfreq/exynos-bus.c +F: Documentation/devicetree/bindings/devfreq/exynos-bus.txt + DEVICE NUMBER REGISTRY M: Torben Mathiasen W: http://lanana.org/docs/device-list/index.html -- 1.9.1
[PATCH v5 07/21] PM / devfreq: exynos: Add support of bus frequency of sub-blocks using passive governor
This patch adds the support of bus frequency feature for sub-blocks which share the one power line. If each bus depends on the power line, each bus is not able to change the voltage by oneself. To optimize the power-consumption on runtime, some buses using the same power line should change the source clock and regulator at the same time. So, this patch uses the passive governor to support the bus frequency for all buses which sharing the one power line. For example, Exynos3250 include the two power line for AXI buses as following: : VDD_MIF : MIF (Memory Interface) provide the DMC (Dynamic Memory Controller) with the power (regulator). : VDD_INT : INT (Internal) provide the various sub-blocks with the power (regulator). Each bus is included in as follwoing block. In the case of VDD_MIF, only DMC bus use the power line. So, there is no any depencency between buese. But, in the case of VDD_INT, various buses share the one power line of VDD_INT. We need to make the depenency between buses. When using passive governor, there is no problem to support the bus frequency as DVFS for all buses. One bus should be operated as the parent bus device which gathering the current load of INT block and then decides the new frequency with some governors except of passive governor. After deciding the new frequency by the parent bus device, the rest bus devices will change the each source clock according to new frequency of the parent bus device. - MIF (Memory Interface) block : VDD_MIF |--- DMC - INT (Internal) block : VDD_INT |--- LEFTBUS (parent) |--- PERIL |--- MFC |--- G3D |--- RIGHTBUS |--- FSYS |--- LCD0 |--- PERIR |--- ISP |--- CAM [tjakobi: Reported debugfs error during booting and cw00.choi fix it.] Reported-by: Tobias JakobiSigned-off-by: Chanwoo Choi --- drivers/devfreq/Kconfig | 1 + drivers/devfreq/exynos-bus.c | 210 +-- 2 files changed, 165 insertions(+), 46 deletions(-) diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index ae689ad375fa..357b548851a3 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -77,6 +77,7 @@ config ARM_EXYNOS_BUS_DEVFREQ bool "ARM EXYNOS Generic Memory Bus DEVFREQ Driver" depends on ARCH_EXYNOS select DEVFREQ_GOV_SIMPLE_ONDEMAND + select DEVFREQ_GOV_PASSIVE select DEVFREQ_EVENT_EXYNOS_PPMU select PM_DEVFREQ_EVENT select PM_OPP diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c index f79963187fa1..c4249efaf0e1 100644 --- a/drivers/devfreq/exynos-bus.c +++ b/drivers/devfreq/exynos-bus.c @@ -1,7 +1,7 @@ /* * Generic Exynos Bus frequency driver with DEVFREQ Framework * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * Author : Chanwoo Choi * * This driver support Exynos Bus frequency feature by using @@ -93,7 +93,7 @@ static int exynos_bus_get_event(struct exynos_bus *bus, } /* - * Must necessary function for devfreq governor + * Must necessary function for devfreq simple-ondemand governor */ static int exynos_bus_target(struct device *dev, unsigned long *freq, u32 flags) { @@ -202,59 +202,80 @@ static void exynos_bus_exit(struct device *dev) regulator_disable(bus->regulator); dev_pm_opp_of_remove_table(dev); + clk_disable_unprepare(bus->clk); } -static int exynos_bus_parse_of(struct device_node *np, - struct exynos_bus *bus) +/* + * Must necessary function for devfreq passive governor + */ +static int exynos_bus_passive_target(struct device *dev, unsigned long *freq, + u32 flags) { - struct device *dev = bus->dev; - unsigned long rate; - int i, ret, count, size; + struct exynos_bus *bus = dev_get_drvdata(dev); + struct dev_pm_opp *new_opp; + unsigned long old_freq, new_freq; + int ret = 0; - /* Get the clock to provide each bus with source clock */ - bus->clk = devm_clk_get(dev, "bus"); - if (IS_ERR(bus->clk)) { - dev_err(dev, "failed to get bus clock\n"); - return PTR_ERR(bus->clk); + /* Get new opp-bus instance according to new bus clock */ + rcu_read_lock(); + new_opp = devfreq_recommended_opp(dev, freq, flags); + if (IS_ERR_OR_NULL(new_opp)) { + dev_err(dev, "failed to get recommed opp instance\n"); + rcu_read_unlock(); + return PTR_ERR(new_opp); } - ret = clk_prepare_enable(bus->clk); - if (ret < 0) { - dev_err(dev, "failed to get enable clock\n"); - return ret; - } + new_freq = dev_pm_opp_get_freq(new_opp); + old_freq =
Re: [PATCH v5 00/21] PM / devferq: Add generic exynos bus frequency driver and new passive governor
Dear Anand and Tobias, To Anand, First of all, thanks to your test on previous patchset. I removed the your tested-by tag from this version because I modified the devfreq core using DEVFREQ_TRANSITION_NOTIFIER notifier. I think that this patch-set need to test with this patchset. If you possible, could you please test this patch-set? Thanks in advance. To Tobias, I fixed the following issues reported by you. Thanks your test and report. - RCU locking issue - debugfs error during kernel booting Best Regards, Chanwoo Choi On 2016년 03월 24일 13:25, Chanwoo Choi wrote: > Dear all, > > This patchset uses the DEVFREQ_TRANSITION_NOTIFIER notifier to connecth > devfreq device using ondemand governor and devfreq device using passive > governor. Also I fix the some issue reported by 'Tobias Jakobi' and add the > detailed issue information. But, this patchset don't modify the anything of > Device Tree patches (patch12 ~ patch21) which already got the reviewed-by > from Exynos Soc Maintainer. > > I tested it on exynos3250-rinato and exynos4412-odroidu3 board. > > [Description] > This patch-set includes the two features as following. The generic exynos bus > frequency driver is able to support almost Exynos SoCs for bus frequency > scaling. And the new passive governor is able to make the dependency on > between devices for frequency/voltage scaling. I had posted the patch-set[1] > with the similiar concept. This is is revised version for exynos bus > frequency. > - Generic exynos bus frequency driver > - New passive governor of DEVFREQ framework > [1] https://lkml.org/lkml/2015/1/7/872 > : [PATCHv3 0/8] devfreq: Add generic exynos memory-bus frequency driver > > Changes from v4: > (https://lkml.org/lkml/2015/12/14/43) > - Add new DEVFREQ_TRANSITION_NOTIFIER notifier. The passive > devfreq device recevie the changed frequency of parent > devfreq device through DEVFREQ_TRANSITION_NOTIFIER. > - Add governor type to identify thme using the defined constant > - Modify the passive governor using the DEVFREQ_TRANSITION_NOTIFIER notifier. > - Fix the RCU locking probrlm (Reported-by: Tobias Jakobi) > - Fix the debugfs error during the kernel booting (Reported-by: Tobias Jakobi) > > Changes from v3: > (https://lkml.org/lkml/2015/12/11/75) > - Add the reviewed-by tag from Krzysztof Kozlowski (patch2/3/13/14/15/16/17) > - Fix typo of the description on patch14 > - Modify the subject and description of patch17 > - Reorder the 'bus_xxx' device tree node alphabetically in > both exynos3250-rinato/monk.dts and exynos4412-trats/odroidu3 > > Changes from v2: > (https://lkml.org/lkml/2015/12/8/869) > - Fix typo on documentation > - Modify the more appropriate sentence on patch description > - Add the detailed description about both parent and passive bus device > - Modify the DMC frequency for Exynos4x12 DMC bus (200MHz -> 267MHz) > - Modify the voltage of 200MHz was included in Exynos3250 DMC bus (800mV -> > 825mV) > - Rename OPP nodes as 'opp@' > - Delete the duplicate 'opp-microvolt' property of passive devfreq device > - Reorder the 'bus_xxx' device tree node alphabetically in > exynos3250-rinato/monk.dts > - Reorder the 'bus_xxx' device tree node alphabetically in > exynos4412-trats/odroidu3 > - Add new exynos4412-ppmu-common.dtsi to remove the duplicate PPMU dt node > on rinato/monk/trats2/odroid-u3 board > - Add the log message if bus device is registered to devfreq framework > successfully > - Add the reviewed-by tag from Krzysztof Kozlowski > - Add the tested-by tag from Anand Moon on Odroid U3 > - Add 'SAMSUNG BUS FREQUENCY DRIVER' entry to MAINTAINERS > > Changes from v1: > (https://lkml.org/lkml/2015/11/26/260) > - Check whether the instance of regulator is NULL or not > when executing regulator_disable() because of only parent > devfreq device has the regulator instance. After fixing it, > the wake-up from suspend state is well working. (patch1) > - Fix bug which checks 'bus-clk' instead of 'bus->regulator' > after calling devm_clk_get() (on patch1) > - Update the documentation to remove the description about > DEVFREQ-EVENT subsystem (on patch2) > - Add the full name of DMC (Dynamic Memory Controller) (on patch2) > - Modify the detailed correlation of buses for Exynos3250 > on documentation (patch2) > - Add the MFC bus node for Exynos3250 (on patch11, patch12) > - Fix the duplicate frequency of bus_display on Exynos4x12.dtsi > - Add the PPMU node for exynos4412-odroidu3 > - Add the support of bus frequency for exynos4412-odroidu3 > > Detailed descirption for patch-set: > 1. Add generic exynos bus frequency driver > : This patch-set adds the generic exynos bus frequency driver for AXI bus > of sub-blocks in exynos SoC. The Samsung Exynos SoC have the common > architecture for bus between DRAM and sub-blocks in SoC. > > There are the different buses according to Exynos SoC because Exynos SoC > has the differnt sub-blocks and bus speed. In spite of this difference > among Exynos SoCs,
[PATCH v5 07/21] PM / devfreq: exynos: Add support of bus frequency of sub-blocks using passive governor
This patch adds the support of bus frequency feature for sub-blocks which share the one power line. If each bus depends on the power line, each bus is not able to change the voltage by oneself. To optimize the power-consumption on runtime, some buses using the same power line should change the source clock and regulator at the same time. So, this patch uses the passive governor to support the bus frequency for all buses which sharing the one power line. For example, Exynos3250 include the two power line for AXI buses as following: : VDD_MIF : MIF (Memory Interface) provide the DMC (Dynamic Memory Controller) with the power (regulator). : VDD_INT : INT (Internal) provide the various sub-blocks with the power (regulator). Each bus is included in as follwoing block. In the case of VDD_MIF, only DMC bus use the power line. So, there is no any depencency between buese. But, in the case of VDD_INT, various buses share the one power line of VDD_INT. We need to make the depenency between buses. When using passive governor, there is no problem to support the bus frequency as DVFS for all buses. One bus should be operated as the parent bus device which gathering the current load of INT block and then decides the new frequency with some governors except of passive governor. After deciding the new frequency by the parent bus device, the rest bus devices will change the each source clock according to new frequency of the parent bus device. - MIF (Memory Interface) block : VDD_MIF |--- DMC - INT (Internal) block : VDD_INT |--- LEFTBUS (parent) |--- PERIL |--- MFC |--- G3D |--- RIGHTBUS |--- FSYS |--- LCD0 |--- PERIR |--- ISP |--- CAM [tjakobi: Reported debugfs error during booting and cw00.choi fix it.] Reported-by: Tobias Jakobi Signed-off-by: Chanwoo Choi --- drivers/devfreq/Kconfig | 1 + drivers/devfreq/exynos-bus.c | 210 +-- 2 files changed, 165 insertions(+), 46 deletions(-) diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index ae689ad375fa..357b548851a3 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -77,6 +77,7 @@ config ARM_EXYNOS_BUS_DEVFREQ bool "ARM EXYNOS Generic Memory Bus DEVFREQ Driver" depends on ARCH_EXYNOS select DEVFREQ_GOV_SIMPLE_ONDEMAND + select DEVFREQ_GOV_PASSIVE select DEVFREQ_EVENT_EXYNOS_PPMU select PM_DEVFREQ_EVENT select PM_OPP diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c index f79963187fa1..c4249efaf0e1 100644 --- a/drivers/devfreq/exynos-bus.c +++ b/drivers/devfreq/exynos-bus.c @@ -1,7 +1,7 @@ /* * Generic Exynos Bus frequency driver with DEVFREQ Framework * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * Author : Chanwoo Choi * * This driver support Exynos Bus frequency feature by using @@ -93,7 +93,7 @@ static int exynos_bus_get_event(struct exynos_bus *bus, } /* - * Must necessary function for devfreq governor + * Must necessary function for devfreq simple-ondemand governor */ static int exynos_bus_target(struct device *dev, unsigned long *freq, u32 flags) { @@ -202,59 +202,80 @@ static void exynos_bus_exit(struct device *dev) regulator_disable(bus->regulator); dev_pm_opp_of_remove_table(dev); + clk_disable_unprepare(bus->clk); } -static int exynos_bus_parse_of(struct device_node *np, - struct exynos_bus *bus) +/* + * Must necessary function for devfreq passive governor + */ +static int exynos_bus_passive_target(struct device *dev, unsigned long *freq, + u32 flags) { - struct device *dev = bus->dev; - unsigned long rate; - int i, ret, count, size; + struct exynos_bus *bus = dev_get_drvdata(dev); + struct dev_pm_opp *new_opp; + unsigned long old_freq, new_freq; + int ret = 0; - /* Get the clock to provide each bus with source clock */ - bus->clk = devm_clk_get(dev, "bus"); - if (IS_ERR(bus->clk)) { - dev_err(dev, "failed to get bus clock\n"); - return PTR_ERR(bus->clk); + /* Get new opp-bus instance according to new bus clock */ + rcu_read_lock(); + new_opp = devfreq_recommended_opp(dev, freq, flags); + if (IS_ERR_OR_NULL(new_opp)) { + dev_err(dev, "failed to get recommed opp instance\n"); + rcu_read_unlock(); + return PTR_ERR(new_opp); } - ret = clk_prepare_enable(bus->clk); - if (ret < 0) { - dev_err(dev, "failed to get enable clock\n"); - return ret; - } + new_freq = dev_pm_opp_get_freq(new_opp); + old_freq = dev_pm_opp_get_freq(bus->curr_opp); + rcu_read_unlock(); - /* Get the freq/voltage OPP table to
Re: [PATCH v5 00/21] PM / devferq: Add generic exynos bus frequency driver and new passive governor
Dear Anand and Tobias, To Anand, First of all, thanks to your test on previous patchset. I removed the your tested-by tag from this version because I modified the devfreq core using DEVFREQ_TRANSITION_NOTIFIER notifier. I think that this patch-set need to test with this patchset. If you possible, could you please test this patch-set? Thanks in advance. To Tobias, I fixed the following issues reported by you. Thanks your test and report. - RCU locking issue - debugfs error during kernel booting Best Regards, Chanwoo Choi On 2016년 03월 24일 13:25, Chanwoo Choi wrote: > Dear all, > > This patchset uses the DEVFREQ_TRANSITION_NOTIFIER notifier to connecth > devfreq device using ondemand governor and devfreq device using passive > governor. Also I fix the some issue reported by 'Tobias Jakobi' and add the > detailed issue information. But, this patchset don't modify the anything of > Device Tree patches (patch12 ~ patch21) which already got the reviewed-by > from Exynos Soc Maintainer. > > I tested it on exynos3250-rinato and exynos4412-odroidu3 board. > > [Description] > This patch-set includes the two features as following. The generic exynos bus > frequency driver is able to support almost Exynos SoCs for bus frequency > scaling. And the new passive governor is able to make the dependency on > between devices for frequency/voltage scaling. I had posted the patch-set[1] > with the similiar concept. This is is revised version for exynos bus > frequency. > - Generic exynos bus frequency driver > - New passive governor of DEVFREQ framework > [1] https://lkml.org/lkml/2015/1/7/872 > : [PATCHv3 0/8] devfreq: Add generic exynos memory-bus frequency driver > > Changes from v4: > (https://lkml.org/lkml/2015/12/14/43) > - Add new DEVFREQ_TRANSITION_NOTIFIER notifier. The passive > devfreq device recevie the changed frequency of parent > devfreq device through DEVFREQ_TRANSITION_NOTIFIER. > - Add governor type to identify thme using the defined constant > - Modify the passive governor using the DEVFREQ_TRANSITION_NOTIFIER notifier. > - Fix the RCU locking probrlm (Reported-by: Tobias Jakobi) > - Fix the debugfs error during the kernel booting (Reported-by: Tobias Jakobi) > > Changes from v3: > (https://lkml.org/lkml/2015/12/11/75) > - Add the reviewed-by tag from Krzysztof Kozlowski (patch2/3/13/14/15/16/17) > - Fix typo of the description on patch14 > - Modify the subject and description of patch17 > - Reorder the 'bus_xxx' device tree node alphabetically in > both exynos3250-rinato/monk.dts and exynos4412-trats/odroidu3 > > Changes from v2: > (https://lkml.org/lkml/2015/12/8/869) > - Fix typo on documentation > - Modify the more appropriate sentence on patch description > - Add the detailed description about both parent and passive bus device > - Modify the DMC frequency for Exynos4x12 DMC bus (200MHz -> 267MHz) > - Modify the voltage of 200MHz was included in Exynos3250 DMC bus (800mV -> > 825mV) > - Rename OPP nodes as 'opp@' > - Delete the duplicate 'opp-microvolt' property of passive devfreq device > - Reorder the 'bus_xxx' device tree node alphabetically in > exynos3250-rinato/monk.dts > - Reorder the 'bus_xxx' device tree node alphabetically in > exynos4412-trats/odroidu3 > - Add new exynos4412-ppmu-common.dtsi to remove the duplicate PPMU dt node > on rinato/monk/trats2/odroid-u3 board > - Add the log message if bus device is registered to devfreq framework > successfully > - Add the reviewed-by tag from Krzysztof Kozlowski > - Add the tested-by tag from Anand Moon on Odroid U3 > - Add 'SAMSUNG BUS FREQUENCY DRIVER' entry to MAINTAINERS > > Changes from v1: > (https://lkml.org/lkml/2015/11/26/260) > - Check whether the instance of regulator is NULL or not > when executing regulator_disable() because of only parent > devfreq device has the regulator instance. After fixing it, > the wake-up from suspend state is well working. (patch1) > - Fix bug which checks 'bus-clk' instead of 'bus->regulator' > after calling devm_clk_get() (on patch1) > - Update the documentation to remove the description about > DEVFREQ-EVENT subsystem (on patch2) > - Add the full name of DMC (Dynamic Memory Controller) (on patch2) > - Modify the detailed correlation of buses for Exynos3250 > on documentation (patch2) > - Add the MFC bus node for Exynos3250 (on patch11, patch12) > - Fix the duplicate frequency of bus_display on Exynos4x12.dtsi > - Add the PPMU node for exynos4412-odroidu3 > - Add the support of bus frequency for exynos4412-odroidu3 > > Detailed descirption for patch-set: > 1. Add generic exynos bus frequency driver > : This patch-set adds the generic exynos bus frequency driver for AXI bus > of sub-blocks in exynos SoC. The Samsung Exynos SoC have the common > architecture for bus between DRAM and sub-blocks in SoC. > > There are the different buses according to Exynos SoC because Exynos SoC > has the differnt sub-blocks and bus speed. In spite of this difference > among Exynos SoCs,
[PATCH v5 06/21] PM / devfreq: Add new passive governor
This patch adds the new passive governor for DEVFREQ framework. The following governors are already present and used for DVFS (Dynamic Voltage and Frequency Scaling) drivers. The following governors are independently used for one device driver which don't give the influence to other device drviers and also don't receive the effect from other device drivers. - ondemand / performance / powersave / userspace The passive governor depends on operation of parent driver with specific governos extremely and is not able to decide the new frequency by oneself. According to the decided new frequency of parent driver with governor, the passive governor uses it to decide the appropriate frequency for own device driver. The passive governor must need the following information from device tree: - the source clock and OPP tables - the instance of parent device For exameple, there are one more devfreq device drivers which need to change their source clock according to their utilization on runtime. But, they share the same power line (e.g., regulator). So, specific device driver is operated as parent with ondemand governor and then the rest device driver with passive governor is influenced by parent device. Suggested-by: Myungjoo Ham[tjakobi: Reported RCU locking issue and cw00.choi fix it.] Reported-by: Tobias Jakobi Signed-off-by: Chanwoo Choi --- drivers/devfreq/Kconfig| 7 ++ drivers/devfreq/Makefile | 1 + drivers/devfreq/devfreq.c | 17 drivers/devfreq/governor.h | 15 +++ drivers/devfreq/governor_passive.c | 192 + include/linux/devfreq.h| 3 + 6 files changed, 235 insertions(+) create mode 100644 drivers/devfreq/governor_passive.c diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 55ec774f794c..ae689ad375fa 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -64,6 +64,13 @@ config DEVFREQ_GOV_USERSPACE Otherwise, the governor does not change the frequnecy given at the initialization. +config DEVFREQ_GOV_PASSIVE + tristate "Passive" + help + Sets the frequency based on the frequency of its parent devfreq + device. This governor does not change the frequency by itself + through sysfs entries. + comment "DEVFREQ Drivers" config ARM_EXYNOS_BUS_DEVFREQ diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile index 8af8aaf922a8..2633087d5c63 100644 --- a/drivers/devfreq/Makefile +++ b/drivers/devfreq/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND) += governor_simpleondemand.o obj-$(CONFIG_DEVFREQ_GOV_PERFORMANCE) += governor_performance.o obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE)+= governor_powersave.o obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)+= governor_userspace.o +obj-$(CONFIG_DEVFREQ_GOV_PASSIVE) += governor_passive.o # DEVFREQ Drivers obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 1d6c803804d5..9f84bbc2994c 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -478,7 +478,13 @@ static void _remove_devfreq(struct devfreq *devfreq) dev_warn(>dev, "releasing devfreq which doesn't exist\n"); return; } + + if (devfreq->governor->type == DEVFREQ_GOV_PASSIVE) + devfreq_passive_unregister_notifier(devfreq); + list_del(>node); + list_del_init(>passive_node); + mutex_unlock(_list_lock); if (devfreq->governor) @@ -598,6 +604,17 @@ struct devfreq *devfreq_add_device(struct device *dev, goto err_init; } + if (devfreq->governor->type == DEVFREQ_GOV_PASSIVE) { + struct devfreq *parent_devfreq = (struct devfreq *)data; + list_add(>passive_node, _devfreq->passive_node); + + err = devfreq_passive_register_notifier(devfreq); + if (err <0) + goto err_init; + } else { + INIT_LIST_HEAD(>passive_node); + } + return devfreq; err_init: diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h index cf19b923c362..64d1dffcdb43 100644 --- a/drivers/devfreq/governor.h +++ b/drivers/devfreq/governor.h @@ -23,6 +23,7 @@ #define DEVFREQ_GOV_PERFORMANCE0x2 #define DEVFREQ_GOV_POWERSAVE 0x3 #define DEVFREQ_GOV_USERSPACE 0x4 +#define DEVFREQ_GOV_PASSIVE0x5 /* Devfreq events */ #define DEVFREQ_GOV_START 0x1 @@ -44,4 +45,18 @@ extern void devfreq_interval_update(struct devfreq *devfreq, extern int devfreq_add_governor(struct devfreq_governor *governor); extern int devfreq_remove_governor(struct devfreq_governor *governor); +#if IS_ENABLED(CONFIG_DEVFREQ_GOV_PASSIVE) +extern
[PATCH v5 06/21] PM / devfreq: Add new passive governor
This patch adds the new passive governor for DEVFREQ framework. The following governors are already present and used for DVFS (Dynamic Voltage and Frequency Scaling) drivers. The following governors are independently used for one device driver which don't give the influence to other device drviers and also don't receive the effect from other device drivers. - ondemand / performance / powersave / userspace The passive governor depends on operation of parent driver with specific governos extremely and is not able to decide the new frequency by oneself. According to the decided new frequency of parent driver with governor, the passive governor uses it to decide the appropriate frequency for own device driver. The passive governor must need the following information from device tree: - the source clock and OPP tables - the instance of parent device For exameple, there are one more devfreq device drivers which need to change their source clock according to their utilization on runtime. But, they share the same power line (e.g., regulator). So, specific device driver is operated as parent with ondemand governor and then the rest device driver with passive governor is influenced by parent device. Suggested-by: Myungjoo Ham [tjakobi: Reported RCU locking issue and cw00.choi fix it.] Reported-by: Tobias Jakobi Signed-off-by: Chanwoo Choi --- drivers/devfreq/Kconfig| 7 ++ drivers/devfreq/Makefile | 1 + drivers/devfreq/devfreq.c | 17 drivers/devfreq/governor.h | 15 +++ drivers/devfreq/governor_passive.c | 192 + include/linux/devfreq.h| 3 + 6 files changed, 235 insertions(+) create mode 100644 drivers/devfreq/governor_passive.c diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 55ec774f794c..ae689ad375fa 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -64,6 +64,13 @@ config DEVFREQ_GOV_USERSPACE Otherwise, the governor does not change the frequnecy given at the initialization. +config DEVFREQ_GOV_PASSIVE + tristate "Passive" + help + Sets the frequency based on the frequency of its parent devfreq + device. This governor does not change the frequency by itself + through sysfs entries. + comment "DEVFREQ Drivers" config ARM_EXYNOS_BUS_DEVFREQ diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile index 8af8aaf922a8..2633087d5c63 100644 --- a/drivers/devfreq/Makefile +++ b/drivers/devfreq/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND) += governor_simpleondemand.o obj-$(CONFIG_DEVFREQ_GOV_PERFORMANCE) += governor_performance.o obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE)+= governor_powersave.o obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)+= governor_userspace.o +obj-$(CONFIG_DEVFREQ_GOV_PASSIVE) += governor_passive.o # DEVFREQ Drivers obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 1d6c803804d5..9f84bbc2994c 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -478,7 +478,13 @@ static void _remove_devfreq(struct devfreq *devfreq) dev_warn(>dev, "releasing devfreq which doesn't exist\n"); return; } + + if (devfreq->governor->type == DEVFREQ_GOV_PASSIVE) + devfreq_passive_unregister_notifier(devfreq); + list_del(>node); + list_del_init(>passive_node); + mutex_unlock(_list_lock); if (devfreq->governor) @@ -598,6 +604,17 @@ struct devfreq *devfreq_add_device(struct device *dev, goto err_init; } + if (devfreq->governor->type == DEVFREQ_GOV_PASSIVE) { + struct devfreq *parent_devfreq = (struct devfreq *)data; + list_add(>passive_node, _devfreq->passive_node); + + err = devfreq_passive_register_notifier(devfreq); + if (err <0) + goto err_init; + } else { + INIT_LIST_HEAD(>passive_node); + } + return devfreq; err_init: diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h index cf19b923c362..64d1dffcdb43 100644 --- a/drivers/devfreq/governor.h +++ b/drivers/devfreq/governor.h @@ -23,6 +23,7 @@ #define DEVFREQ_GOV_PERFORMANCE0x2 #define DEVFREQ_GOV_POWERSAVE 0x3 #define DEVFREQ_GOV_USERSPACE 0x4 +#define DEVFREQ_GOV_PASSIVE0x5 /* Devfreq events */ #define DEVFREQ_GOV_START 0x1 @@ -44,4 +45,18 @@ extern void devfreq_interval_update(struct devfreq *devfreq, extern int devfreq_add_governor(struct devfreq_governor *governor); extern int devfreq_remove_governor(struct devfreq_governor *governor); +#if IS_ENABLED(CONFIG_DEVFREQ_GOV_PASSIVE) +extern int devfreq_passive_register_notifier(struct devfreq *passive); +extern void
[PATCH v5 12/21] ARM: dts: Add DMC bus node for Exynos3250
This patch adds the DMC (Dynamic Memory Controller) bus node for Exynos3250 SoC. The DMC is an AMBA AXI-compliant slave to interface external JEDEC standard SDRAM devices. The bus includes the OPP tables and the source clock for DMC block. Following list specifies the detailed relation between the clock and DMC block: - The source clock of DMC block : div_dmc Signed-off-by: Chanwoo ChoiReviewed-by: Krzysztof Kozlowski Acked-by: MyungJoo Ham --- arch/arm/boot/dts/exynos3250.dtsi | 34 ++ 1 file changed, 34 insertions(+) diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi index 137f9015d4e8..1ae72c4fa55e 100644 --- a/arch/arm/boot/dts/exynos3250.dtsi +++ b/arch/arm/boot/dts/exynos3250.dtsi @@ -688,6 +688,40 @@ clock-names = "ppmu"; status = "disabled"; }; + + bus_dmc: bus_dmc { + compatible = "samsung,exynos-bus"; + clocks = <_dmc CLK_DIV_DMC>; + clock-names = "bus"; + operating-points-v2 = <_dmc_opp_table>; + status = "disabled"; + }; + + bus_dmc_opp_table: opp_table1 { + compatible = "operating-points-v2"; + opp-shared; + + opp@5000 { + opp-hz = /bits/ 64 <5000>; + opp-microvolt = <80>; + }; + opp@1 { + opp-hz = /bits/ 64 <1>; + opp-microvolt = <80>; + }; + opp@13400 { + opp-hz = /bits/ 64 <13400>; + opp-microvolt = <80>; + }; + opp@2 { + opp-hz = /bits/ 64 <2>; + opp-microvolt = <825000>; + }; + opp@4 { + opp-hz = /bits/ 64 <4>; + opp-microvolt = <875000>; + }; + }; }; }; -- 1.9.1
[PATCH v5 13/21] ARM: dts: Add DMC bus frequency for exynos3250-rinato/monk
This patch adds the DMC (Dynamic Memory Controller) bus frequency node which includes the devfreq-events and regulator properties. The bus frequency support the DVFS (Dynamic Voltage Frequency Scaling) feature with ondemand governor. The devfreq-events (ppmu_dmc0*) can monitor the utilization of DMC bus on runtime and the buck1_reg (VDD_MIF power line) supplies the power to the DMC block. Signed-off-by: Chanwoo ChoiReviewed-by: Krzysztof Kozlowski Acked-by: MyungJoo Ham --- arch/arm/boot/dts/exynos3250-monk.dts | 6 ++ arch/arm/boot/dts/exynos3250-rinato.dts | 6 ++ 2 files changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts index 9e2840b59ae8..1fd7ecb5c415 100644 --- a/arch/arm/boot/dts/exynos3250-monk.dts +++ b/arch/arm/boot/dts/exynos3250-monk.dts @@ -156,6 +156,12 @@ }; }; +_dmc { + devfreq-events = <_dmc0_3>, <_dmc1_3>; + vdd-supply = <_reg>; + status = "okay"; +}; + { cpu0-supply = <_reg>; }; diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts index 1f102f3a1ab1..5175bd7e015f 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts +++ b/arch/arm/boot/dts/exynos3250-rinato.dts @@ -147,6 +147,12 @@ }; }; +_dmc { + devfreq-events = <_dmc0_3>, <_dmc1_3>; + vdd-supply = <_reg>; + status = "okay"; +}; + { cpu0-supply = <_reg>; }; -- 1.9.1
[PATCH v5 02/21] PM / devfreq: exynos: Add documentation for generic exynos bus frequency driver
This patch adds the documentation for generic exynos bus frequency driver. Signed-off-by: Chanwoo ChoiReviewed-by: Krzysztof Kozlowski --- .../devicetree/bindings/devfreq/exynos-bus.txt | 95 ++ 1 file changed, 95 insertions(+) create mode 100644 Documentation/devicetree/bindings/devfreq/exynos-bus.txt diff --git a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt new file mode 100644 index ..78171b918e3f --- /dev/null +++ b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt @@ -0,0 +1,95 @@ +* Generic Exynos Bus frequency device + +The Samsung Exynos SoC has many buses for data transfer between DRAM +and sub-blocks in SoC. Most Exynos SoCs share the common architecture +for buses. Generally, each bus of Exynos SoC includes a source clock +and a power line, which are able to change the clock frequency +of the bus in runtime. To monitor the usage of each bus in runtime, +the driver uses the PPMU (Platform Performance Monitoring Unit), which +is able to measure the current load of sub-blocks. + +There are a little different composition among Exynos SoC because each Exynos +SoC has different sub-blocks. Therefore, shch difference should be specified +in devicetree file instead of each device driver. In result, this driver +is able to support the bus frequency for all Exynos SoCs. + +Required properties for bus device: +- compatible: Should be "samsung,exynos-bus". +- clock-names : the name of clock used by the bus, "bus". +- clocks : phandles for clock specified in "clock-names" property. +- operating-points-v2: the OPP table including frequency/voltage information + to support DVFS (Dynamic Voltage/Frequency Scaling) feature. +- vdd-supply: the regulator to provide the buses with the voltage. +- devfreq-events: the devfreq-event device to monitor the current utilization + of buses. + +Optional properties for bus device: +- exynos,saturation-ratio: the percentage value which is used to calibrate + the performance count against total cycle count. +- exynos,voltage-tolerance: the percentage value for bus voltage tolerance + which is used to calculate the max voltage. + +Example1: + Show the AXI buses of Exynos3250 SoC. Exynos3250 divides the buses to + power line (regulator). The MIF (Memory Interface) AXI bus is used to + transfer data between DRAM and CPU and uses the VDD_MIF regualtor. + + - power line(VDD_MIF) --> bus for DMC (Dynamic Memory Controller) block + + - MIF bus's frequency/voltage table + --- + |Lv| Freq | Voltage | + --- + |L1| 5 |80 | + |L2| 10 |80 | + |L3| 134000 |80 | + |L4| 20 |825000 | + |L5| 40 |875000 | + --- + +Example2 : + The bus of DMC (Dynamic Memory Controller) block in exynos3250.dtsi + is listed below: + + bus_dmc: bus_dmc { + compatible = "samsung,exynos-bus"; + clocks = <_dmc CLK_DIV_DMC>; + clock-names = "bus"; + operating-points-v2 = <_dmc_opp_table>; + status = "disabled"; + }; + + bus_dmc_opp_table: opp_table1 { + compatible = "operating-points-v2"; + opp-shared; + + opp@5000 { + opp-hz = /bits/ 64 <5000>; + opp-microvolt = <80>; + }; + opp@1 { + opp-hz = /bits/ 64 <1>; + opp-microvolt = <80>; + }; + opp@13400 { + opp-hz = /bits/ 64 <13400>; + opp-microvolt = <80>; + }; + opp@2 { + opp-hz = /bits/ 64 <2>; + opp-microvolt = <825000>; + }; + opp@4 { + opp-hz = /bits/ 64 <4>; + opp-microvolt = <875000>; + }; + }; + + Usage case to handle the frequency and voltage of bus on runtime + in exynos3250-rinato.dts is listed below: + + _dmc { + devfreq-events = <_dmc0_3>, <_dmc1_3>; + vdd-supply = <_reg>; /* VDD_MIF */ + status = "okay"; + }; -- 1.9.1
[PATCH v5 17/21] ARM: dts: Add bus nodes using VDD_MIF for Exynos4210
This patch adds the bus nodes for Exynos4210 SoC. Exynos4210 SoC has one power line for all buses to translate data between DRAM and sub-blocks. Following list specifies the detailed relation between DRAM and sub-blocks: - DMC/ACP clock for DMC (Dynamic Memory Controller) - ACLK200 clock for LCD0 - ACLK100 clock for PERIL/PERIR/MFC(PCLK) - ACLK160 clock for CAM/TV/LCD0/LCD1 - ACLK133 clock for FSYS/GPS - GDL/GDR clock for LEFTBUS/RIGHTBUS - SCLK_MFC clock for MFC Signed-off-by: Chanwoo ChoiReviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos4210.dtsi | 159 ++ 1 file changed, 159 insertions(+) diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi index c1cb8df6da07..2d9b02967105 100644 --- a/arch/arm/boot/dts/exynos4210.dtsi +++ b/arch/arm/boot/dts/exynos4210.dtsi @@ -257,6 +257,165 @@ power-domains = <_lcd1>; #iommu-cells = <0>; }; + + bus_dmc: bus_dmc { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_DMC>; + clock-names = "bus"; + operating-points-v2 = <_dmc_opp_table>; + status = "disabled"; + }; + + bus_acp: bus_acp { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_ACP>; + clock-names = "bus"; + operating-points-v2 = <_acp_opp_table>; + status = "disabled"; + }; + + bus_peri: bus_peri { + compatible = "samsung,exynos-bus"; + clocks = < CLK_ACLK100>; + clock-names = "bus"; + operating-points-v2 = <_peri_opp_table>; + status = "disabled"; + }; + + bus_fsys: bus_fsys { + compatible = "samsung,exynos-bus"; + clocks = < CLK_ACLK133>; + clock-names = "bus"; + operating-points-v2 = <_fsys_opp_table>; + status = "disabled"; + }; + + bus_display: bus_display { + compatible = "samsung,exynos-bus"; + clocks = < CLK_ACLK160>; + clock-names = "bus"; + operating-points-v2 = <_display_opp_table>; + status = "disabled"; + }; + + bus_lcd0: bus_lcd0 { + compatible = "samsung,exynos-bus"; + clocks = < CLK_ACLK200>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_leftbus: bus_leftbus { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_GDL>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_rightbus: bus_rightbus { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_GDR>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_mfc: bus_mfc { + compatible = "samsung,exynos-bus"; + clocks = < CLK_SCLK_MFC>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_dmc_opp_table: opp_table1 { + compatible = "operating-points-v2"; + opp-shared; + + opp@13400 { + opp-hz = /bits/ 64 <13400>; + opp-microvolt = <1025000>; + }; + opp@26700 { + opp-hz = /bits/ 64 <26700>; + opp-microvolt = <105>; + }; + opp@4 { + opp-hz = /bits/ 64 <4>; + opp-microvolt = <115>; + }; + }; + + bus_acp_opp_table: opp_table2 { + compatible = "operating-points-v2"; + opp-shared; + + opp@13400 { + opp-hz = /bits/ 64 <13400>; + }; + opp@16000 { + opp-hz = /bits/ 64 <16000>; + }; + opp@2 { + opp-hz = /bits/ 64 <2>; + }; + }; + + bus_peri_opp_table: opp_table3 { + compatible = "operating-points-v2"; + opp-shared; + + opp@500 { + opp-hz = /bits/ 64 <500>; + }; + opp@1 { + opp-hz = /bits/ 64 <1>; + }; + }; + + bus_fsys_opp_table: opp_table4 { + compatible = "operating-points-v2"; + opp-shared; + + opp@1000 { +
[PATCH v5 12/21] ARM: dts: Add DMC bus node for Exynos3250
This patch adds the DMC (Dynamic Memory Controller) bus node for Exynos3250 SoC. The DMC is an AMBA AXI-compliant slave to interface external JEDEC standard SDRAM devices. The bus includes the OPP tables and the source clock for DMC block. Following list specifies the detailed relation between the clock and DMC block: - The source clock of DMC block : div_dmc Signed-off-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski Acked-by: MyungJoo Ham --- arch/arm/boot/dts/exynos3250.dtsi | 34 ++ 1 file changed, 34 insertions(+) diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi index 137f9015d4e8..1ae72c4fa55e 100644 --- a/arch/arm/boot/dts/exynos3250.dtsi +++ b/arch/arm/boot/dts/exynos3250.dtsi @@ -688,6 +688,40 @@ clock-names = "ppmu"; status = "disabled"; }; + + bus_dmc: bus_dmc { + compatible = "samsung,exynos-bus"; + clocks = <_dmc CLK_DIV_DMC>; + clock-names = "bus"; + operating-points-v2 = <_dmc_opp_table>; + status = "disabled"; + }; + + bus_dmc_opp_table: opp_table1 { + compatible = "operating-points-v2"; + opp-shared; + + opp@5000 { + opp-hz = /bits/ 64 <5000>; + opp-microvolt = <80>; + }; + opp@1 { + opp-hz = /bits/ 64 <1>; + opp-microvolt = <80>; + }; + opp@13400 { + opp-hz = /bits/ 64 <13400>; + opp-microvolt = <80>; + }; + opp@2 { + opp-hz = /bits/ 64 <2>; + opp-microvolt = <825000>; + }; + opp@4 { + opp-hz = /bits/ 64 <4>; + opp-microvolt = <875000>; + }; + }; }; }; -- 1.9.1
[PATCH v5 13/21] ARM: dts: Add DMC bus frequency for exynos3250-rinato/monk
This patch adds the DMC (Dynamic Memory Controller) bus frequency node which includes the devfreq-events and regulator properties. The bus frequency support the DVFS (Dynamic Voltage Frequency Scaling) feature with ondemand governor. The devfreq-events (ppmu_dmc0*) can monitor the utilization of DMC bus on runtime and the buck1_reg (VDD_MIF power line) supplies the power to the DMC block. Signed-off-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski Acked-by: MyungJoo Ham --- arch/arm/boot/dts/exynos3250-monk.dts | 6 ++ arch/arm/boot/dts/exynos3250-rinato.dts | 6 ++ 2 files changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts index 9e2840b59ae8..1fd7ecb5c415 100644 --- a/arch/arm/boot/dts/exynos3250-monk.dts +++ b/arch/arm/boot/dts/exynos3250-monk.dts @@ -156,6 +156,12 @@ }; }; +_dmc { + devfreq-events = <_dmc0_3>, <_dmc1_3>; + vdd-supply = <_reg>; + status = "okay"; +}; + { cpu0-supply = <_reg>; }; diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts index 1f102f3a1ab1..5175bd7e015f 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts +++ b/arch/arm/boot/dts/exynos3250-rinato.dts @@ -147,6 +147,12 @@ }; }; +_dmc { + devfreq-events = <_dmc0_3>, <_dmc1_3>; + vdd-supply = <_reg>; + status = "okay"; +}; + { cpu0-supply = <_reg>; }; -- 1.9.1
[PATCH v5 02/21] PM / devfreq: exynos: Add documentation for generic exynos bus frequency driver
This patch adds the documentation for generic exynos bus frequency driver. Signed-off-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski --- .../devicetree/bindings/devfreq/exynos-bus.txt | 95 ++ 1 file changed, 95 insertions(+) create mode 100644 Documentation/devicetree/bindings/devfreq/exynos-bus.txt diff --git a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt new file mode 100644 index ..78171b918e3f --- /dev/null +++ b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt @@ -0,0 +1,95 @@ +* Generic Exynos Bus frequency device + +The Samsung Exynos SoC has many buses for data transfer between DRAM +and sub-blocks in SoC. Most Exynos SoCs share the common architecture +for buses. Generally, each bus of Exynos SoC includes a source clock +and a power line, which are able to change the clock frequency +of the bus in runtime. To monitor the usage of each bus in runtime, +the driver uses the PPMU (Platform Performance Monitoring Unit), which +is able to measure the current load of sub-blocks. + +There are a little different composition among Exynos SoC because each Exynos +SoC has different sub-blocks. Therefore, shch difference should be specified +in devicetree file instead of each device driver. In result, this driver +is able to support the bus frequency for all Exynos SoCs. + +Required properties for bus device: +- compatible: Should be "samsung,exynos-bus". +- clock-names : the name of clock used by the bus, "bus". +- clocks : phandles for clock specified in "clock-names" property. +- operating-points-v2: the OPP table including frequency/voltage information + to support DVFS (Dynamic Voltage/Frequency Scaling) feature. +- vdd-supply: the regulator to provide the buses with the voltage. +- devfreq-events: the devfreq-event device to monitor the current utilization + of buses. + +Optional properties for bus device: +- exynos,saturation-ratio: the percentage value which is used to calibrate + the performance count against total cycle count. +- exynos,voltage-tolerance: the percentage value for bus voltage tolerance + which is used to calculate the max voltage. + +Example1: + Show the AXI buses of Exynos3250 SoC. Exynos3250 divides the buses to + power line (regulator). The MIF (Memory Interface) AXI bus is used to + transfer data between DRAM and CPU and uses the VDD_MIF regualtor. + + - power line(VDD_MIF) --> bus for DMC (Dynamic Memory Controller) block + + - MIF bus's frequency/voltage table + --- + |Lv| Freq | Voltage | + --- + |L1| 5 |80 | + |L2| 10 |80 | + |L3| 134000 |80 | + |L4| 20 |825000 | + |L5| 40 |875000 | + --- + +Example2 : + The bus of DMC (Dynamic Memory Controller) block in exynos3250.dtsi + is listed below: + + bus_dmc: bus_dmc { + compatible = "samsung,exynos-bus"; + clocks = <_dmc CLK_DIV_DMC>; + clock-names = "bus"; + operating-points-v2 = <_dmc_opp_table>; + status = "disabled"; + }; + + bus_dmc_opp_table: opp_table1 { + compatible = "operating-points-v2"; + opp-shared; + + opp@5000 { + opp-hz = /bits/ 64 <5000>; + opp-microvolt = <80>; + }; + opp@1 { + opp-hz = /bits/ 64 <1>; + opp-microvolt = <80>; + }; + opp@13400 { + opp-hz = /bits/ 64 <13400>; + opp-microvolt = <80>; + }; + opp@2 { + opp-hz = /bits/ 64 <2>; + opp-microvolt = <825000>; + }; + opp@4 { + opp-hz = /bits/ 64 <4>; + opp-microvolt = <875000>; + }; + }; + + Usage case to handle the frequency and voltage of bus on runtime + in exynos3250-rinato.dts is listed below: + + _dmc { + devfreq-events = <_dmc0_3>, <_dmc1_3>; + vdd-supply = <_reg>; /* VDD_MIF */ + status = "okay"; + }; -- 1.9.1
[PATCH v5 17/21] ARM: dts: Add bus nodes using VDD_MIF for Exynos4210
This patch adds the bus nodes for Exynos4210 SoC. Exynos4210 SoC has one power line for all buses to translate data between DRAM and sub-blocks. Following list specifies the detailed relation between DRAM and sub-blocks: - DMC/ACP clock for DMC (Dynamic Memory Controller) - ACLK200 clock for LCD0 - ACLK100 clock for PERIL/PERIR/MFC(PCLK) - ACLK160 clock for CAM/TV/LCD0/LCD1 - ACLK133 clock for FSYS/GPS - GDL/GDR clock for LEFTBUS/RIGHTBUS - SCLK_MFC clock for MFC Signed-off-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos4210.dtsi | 159 ++ 1 file changed, 159 insertions(+) diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi index c1cb8df6da07..2d9b02967105 100644 --- a/arch/arm/boot/dts/exynos4210.dtsi +++ b/arch/arm/boot/dts/exynos4210.dtsi @@ -257,6 +257,165 @@ power-domains = <_lcd1>; #iommu-cells = <0>; }; + + bus_dmc: bus_dmc { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_DMC>; + clock-names = "bus"; + operating-points-v2 = <_dmc_opp_table>; + status = "disabled"; + }; + + bus_acp: bus_acp { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_ACP>; + clock-names = "bus"; + operating-points-v2 = <_acp_opp_table>; + status = "disabled"; + }; + + bus_peri: bus_peri { + compatible = "samsung,exynos-bus"; + clocks = < CLK_ACLK100>; + clock-names = "bus"; + operating-points-v2 = <_peri_opp_table>; + status = "disabled"; + }; + + bus_fsys: bus_fsys { + compatible = "samsung,exynos-bus"; + clocks = < CLK_ACLK133>; + clock-names = "bus"; + operating-points-v2 = <_fsys_opp_table>; + status = "disabled"; + }; + + bus_display: bus_display { + compatible = "samsung,exynos-bus"; + clocks = < CLK_ACLK160>; + clock-names = "bus"; + operating-points-v2 = <_display_opp_table>; + status = "disabled"; + }; + + bus_lcd0: bus_lcd0 { + compatible = "samsung,exynos-bus"; + clocks = < CLK_ACLK200>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_leftbus: bus_leftbus { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_GDL>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_rightbus: bus_rightbus { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_GDR>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_mfc: bus_mfc { + compatible = "samsung,exynos-bus"; + clocks = < CLK_SCLK_MFC>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_dmc_opp_table: opp_table1 { + compatible = "operating-points-v2"; + opp-shared; + + opp@13400 { + opp-hz = /bits/ 64 <13400>; + opp-microvolt = <1025000>; + }; + opp@26700 { + opp-hz = /bits/ 64 <26700>; + opp-microvolt = <105>; + }; + opp@4 { + opp-hz = /bits/ 64 <4>; + opp-microvolt = <115>; + }; + }; + + bus_acp_opp_table: opp_table2 { + compatible = "operating-points-v2"; + opp-shared; + + opp@13400 { + opp-hz = /bits/ 64 <13400>; + }; + opp@16000 { + opp-hz = /bits/ 64 <16000>; + }; + opp@2 { + opp-hz = /bits/ 64 <2>; + }; + }; + + bus_peri_opp_table: opp_table3 { + compatible = "operating-points-v2"; + opp-shared; + + opp@500 { + opp-hz = /bits/ 64 <500>; + }; + opp@1 { + opp-hz = /bits/ 64 <1>; + }; + }; + + bus_fsys_opp_table: opp_table4 { + compatible = "operating-points-v2"; + opp-shared; + + opp@1000 { + opp-hz = /bits/ 64
[PATCH v5 21/21] ARM: dts: Add support of bus frequency for exynos4412-trats/odroidu3
THis patch adds the bus device tree nodes for both MIF (Memory) and INT (Internal) block to enable the bus frequency. The DMC bus is parent device in MIF block using VDD_MIF and the LEFTBUS bus is parent device in INT block using VDD_INT. Signed-off-by: Chanwoo ChoiReviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 47 + arch/arm/boot/dts/exynos4412-trats2.dts | 47 + 2 files changed, 94 insertions(+) diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index b4983cbc4f8c..2015f10071f9 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -109,6 +109,53 @@ }; }; +_dmc { + devfreq-events = <_dmc0_3>, <_dmc1_3>; + vdd-supply = <_reg>; + status = "okay"; +}; + +_acp { + devfreq = <_dmc>; + status = "okay"; +}; + +_c2c { + devfreq = <_dmc>; + status = "okay"; +}; + +_leftbus { + devfreq-events = <_leftbus_3>, <_rightbus_3>; + vdd-supply = <_reg>; + status = "okay"; +}; + +_rightbus { + devfreq = <_leftbus>; + status = "okay"; +}; + +_display { + devfreq = <_leftbus>; + status = "okay"; +}; + +_fsys { + devfreq = <_leftbus>; + status = "okay"; +}; + +_peri { + devfreq = <_leftbus>; + status = "okay"; +}; + +_mfc { + devfreq = <_leftbus>; + status = "okay"; +}; + { cpu0-supply = <_reg>; }; diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index dce3cebe0606..9f3fb9a7f5f4 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -289,6 +289,53 @@ status = "okay"; }; +_dmc { + devfreq-events = <_dmc0_3>, <_dmc1_3>; + vdd-supply = <_reg>; + status = "okay"; +}; + +_acp { + devfreq = <_dmc>; + status = "okay"; +}; + +_c2c { + devfreq = <_dmc>; + status = "okay"; +}; + +_leftbus { + devfreq-events = <_leftbus_3>, <_rightbus_3>; + vdd-supply = <_reg>; + status = "okay"; +}; + +_rightbus { + devfreq = <_leftbus>; + status = "okay"; +}; + +_display { + devfreq = <_leftbus>; + status = "okay"; +}; + +_fsys { + devfreq = <_leftbus>; + status = "okay"; +}; + +_peri { + devfreq = <_leftbus>; + status = "okay"; +}; + +_mfc { + devfreq = <_leftbus>; + status = "okay"; +}; + { cpu0-supply = <_reg>; }; -- 1.9.1
[PATCH v5 21/21] ARM: dts: Add support of bus frequency for exynos4412-trats/odroidu3
THis patch adds the bus device tree nodes for both MIF (Memory) and INT (Internal) block to enable the bus frequency. The DMC bus is parent device in MIF block using VDD_MIF and the LEFTBUS bus is parent device in INT block using VDD_INT. Signed-off-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 47 + arch/arm/boot/dts/exynos4412-trats2.dts | 47 + 2 files changed, 94 insertions(+) diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index b4983cbc4f8c..2015f10071f9 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -109,6 +109,53 @@ }; }; +_dmc { + devfreq-events = <_dmc0_3>, <_dmc1_3>; + vdd-supply = <_reg>; + status = "okay"; +}; + +_acp { + devfreq = <_dmc>; + status = "okay"; +}; + +_c2c { + devfreq = <_dmc>; + status = "okay"; +}; + +_leftbus { + devfreq-events = <_leftbus_3>, <_rightbus_3>; + vdd-supply = <_reg>; + status = "okay"; +}; + +_rightbus { + devfreq = <_leftbus>; + status = "okay"; +}; + +_display { + devfreq = <_leftbus>; + status = "okay"; +}; + +_fsys { + devfreq = <_leftbus>; + status = "okay"; +}; + +_peri { + devfreq = <_leftbus>; + status = "okay"; +}; + +_mfc { + devfreq = <_leftbus>; + status = "okay"; +}; + { cpu0-supply = <_reg>; }; diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index dce3cebe0606..9f3fb9a7f5f4 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -289,6 +289,53 @@ status = "okay"; }; +_dmc { + devfreq-events = <_dmc0_3>, <_dmc1_3>; + vdd-supply = <_reg>; + status = "okay"; +}; + +_acp { + devfreq = <_dmc>; + status = "okay"; +}; + +_c2c { + devfreq = <_dmc>; + status = "okay"; +}; + +_leftbus { + devfreq-events = <_leftbus_3>, <_rightbus_3>; + vdd-supply = <_reg>; + status = "okay"; +}; + +_rightbus { + devfreq = <_leftbus>; + status = "okay"; +}; + +_display { + devfreq = <_leftbus>; + status = "okay"; +}; + +_fsys { + devfreq = <_leftbus>; + status = "okay"; +}; + +_peri { + devfreq = <_leftbus>; + status = "okay"; +}; + +_mfc { + devfreq = <_leftbus>; + status = "okay"; +}; + { cpu0-supply = <_reg>; }; -- 1.9.1
[PATCH v5 03/21] PM / devfreq: Add devfreq_get_devfreq_by_phandle()
This patch adds the new devfreq_get_devfreq_by_phandle() OF helper function which can find the instance of devfreq device by using phandle ("devfreq"). Signed-off-by: Chanwoo ChoiSigned-off-by: MyungJoo Ham --- drivers/devfreq/devfreq.c | 44 include/linux/devfreq.h | 9 + 2 files changed, 53 insertions(+) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 984c5e9e7bdd..20a9422c2552 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "governor.h" static struct class *devfreq_class; @@ -639,6 +640,49 @@ struct devfreq *devm_devfreq_add_device(struct device *dev, } EXPORT_SYMBOL(devm_devfreq_add_device); +#ifdef CONFIG_OF +/* + * devfreq_get_devfreq_by_phandle - Get the devfreq device from devicetree + * @dev - instance to the given device + * @index - index into list of devfreq + * + * return the instance of devfreq device + */ +struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, int index) +{ + struct device_node *node; + struct devfreq *devfreq; + + if (!dev) + return ERR_PTR(-EINVAL); + + if (!dev->of_node) + return ERR_PTR(-EINVAL); + + node = of_parse_phandle(dev->of_node, "devfreq", index); + if (!node) + return ERR_PTR(-ENODEV); + + mutex_lock(_list_lock); + list_for_each_entry(devfreq, _list, node) { + if (devfreq->dev.parent + && devfreq->dev.parent->of_node == node) { + mutex_unlock(_list_lock); + return devfreq; + } + } + mutex_unlock(_list_lock); + + return ERR_PTR(-EPROBE_DEFER); +} +#else +struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, int index) +{ + return ERR_PTR(-ENODEV); +} +#endif /* CONFIG_OF */ +EXPORT_SYMBOL_GPL(devfreq_get_devfreq_by_phandle); + /** * devm_devfreq_remove_device() - Resource-managed devfreq_remove_device() * @dev: the device to add devfreq feature. diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 6fa02a20eb63..aa0b8424ebc3 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -208,6 +208,9 @@ extern int devm_devfreq_register_opp_notifier(struct device *dev, extern void devm_devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq); +extern struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, + int index); + /** * devfreq_update_stats() - update the last_status pointer in struct devfreq * @df:the devfreq instance whose status needs updating @@ -307,6 +310,12 @@ static inline void devm_devfreq_unregister_opp_notifier(struct device *dev, { } +static inline struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, + int index) +{ + return ERR_PTR(-ENODEV); +} + static inline int devfreq_update_stats(struct devfreq *df) { return -EINVAL; -- 1.9.1
[PATCH v5 14/21] ARM: dts: Add bus nodes using VDD_INT for Exynos3250
This patch adds the bus nodes using VDD_INT for Exynos3250 SoC. Exynos3250 has following AXI buses to translate data between DRAM and sub-blocks. Following list specifies the detailed relation between DRAM and sub-blocks: - ACLK400 clock for MCUISP - ACLK266 clock for ISP - ACLK200 clock for FSYS - ACLK160 clock for LCD0 - ACLK100 clock for PERIL - GDL clock for LEFTBUS - GDR clock for RIGHTBUS - SCLK_MFC clock for MFC Signed-off-by: Chanwoo ChoiReviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos3250.dtsi | 147 ++ 1 file changed, 147 insertions(+) diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi index 1ae72c4fa55e..b5157492a422 100644 --- a/arch/arm/boot/dts/exynos3250.dtsi +++ b/arch/arm/boot/dts/exynos3250.dtsi @@ -722,6 +722,153 @@ opp-microvolt = <875000>; }; }; + + bus_leftbus: bus_leftbus { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_GDL>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_rightbus: bus_rightbus { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_GDR>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_lcd0: bus_lcd0 { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_ACLK_160>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_fsys: bus_fsys { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_ACLK_200>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_mcuisp: bus_mcuisp { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_ACLK_400_MCUISP>; + clock-names = "bus"; + operating-points-v2 = <_mcuisp_opp_table>; + status = "disabled"; + }; + + bus_isp: bus_isp { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_ACLK_266>; + clock-names = "bus"; + operating-points-v2 = <_isp_opp_table>; + status = "disabled"; + }; + + bus_peril: bus_peril { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_ACLK_100>; + clock-names = "bus"; + operating-points-v2 = <_peril_opp_table>; + status = "disabled"; + }; + + bus_mfc: bus_mfc { + compatible = "samsung,exynos-bus"; + clocks = < CLK_SCLK_MFC>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_leftbus_opp_table: opp_table2 { + compatible = "operating-points-v2"; + opp-shared; + + opp@5000 { + opp-hz = /bits/ 64 <5000>; + opp-microvolt = <90>; + }; + opp@8000 { + opp-hz = /bits/ 64 <8000>; + opp-microvolt = <90>; + }; + opp@1 { + opp-hz = /bits/ 64 <1>; + opp-microvolt = <100>; + }; + opp@13400 { + opp-hz = /bits/ 64 <13400>; + opp-microvolt = <100>; + }; + opp@2 { + opp-hz = /bits/ 64 <2>; + opp-microvolt = <100>; + }; + }; + + bus_mcuisp_opp_table: opp_table3 { + compatible = "operating-points-v2"; + opp-shared; + + opp@5000 { + opp-hz = /bits/ 64 <5000>; +
[PATCH v5 03/21] PM / devfreq: Add devfreq_get_devfreq_by_phandle()
This patch adds the new devfreq_get_devfreq_by_phandle() OF helper function which can find the instance of devfreq device by using phandle ("devfreq"). Signed-off-by: Chanwoo Choi Signed-off-by: MyungJoo Ham --- drivers/devfreq/devfreq.c | 44 include/linux/devfreq.h | 9 + 2 files changed, 53 insertions(+) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 984c5e9e7bdd..20a9422c2552 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "governor.h" static struct class *devfreq_class; @@ -639,6 +640,49 @@ struct devfreq *devm_devfreq_add_device(struct device *dev, } EXPORT_SYMBOL(devm_devfreq_add_device); +#ifdef CONFIG_OF +/* + * devfreq_get_devfreq_by_phandle - Get the devfreq device from devicetree + * @dev - instance to the given device + * @index - index into list of devfreq + * + * return the instance of devfreq device + */ +struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, int index) +{ + struct device_node *node; + struct devfreq *devfreq; + + if (!dev) + return ERR_PTR(-EINVAL); + + if (!dev->of_node) + return ERR_PTR(-EINVAL); + + node = of_parse_phandle(dev->of_node, "devfreq", index); + if (!node) + return ERR_PTR(-ENODEV); + + mutex_lock(_list_lock); + list_for_each_entry(devfreq, _list, node) { + if (devfreq->dev.parent + && devfreq->dev.parent->of_node == node) { + mutex_unlock(_list_lock); + return devfreq; + } + } + mutex_unlock(_list_lock); + + return ERR_PTR(-EPROBE_DEFER); +} +#else +struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, int index) +{ + return ERR_PTR(-ENODEV); +} +#endif /* CONFIG_OF */ +EXPORT_SYMBOL_GPL(devfreq_get_devfreq_by_phandle); + /** * devm_devfreq_remove_device() - Resource-managed devfreq_remove_device() * @dev: the device to add devfreq feature. diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 6fa02a20eb63..aa0b8424ebc3 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -208,6 +208,9 @@ extern int devm_devfreq_register_opp_notifier(struct device *dev, extern void devm_devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq); +extern struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, + int index); + /** * devfreq_update_stats() - update the last_status pointer in struct devfreq * @df:the devfreq instance whose status needs updating @@ -307,6 +310,12 @@ static inline void devm_devfreq_unregister_opp_notifier(struct device *dev, { } +static inline struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, + int index) +{ + return ERR_PTR(-ENODEV); +} + static inline int devfreq_update_stats(struct devfreq *df) { return -EINVAL; -- 1.9.1
[PATCH v5 14/21] ARM: dts: Add bus nodes using VDD_INT for Exynos3250
This patch adds the bus nodes using VDD_INT for Exynos3250 SoC. Exynos3250 has following AXI buses to translate data between DRAM and sub-blocks. Following list specifies the detailed relation between DRAM and sub-blocks: - ACLK400 clock for MCUISP - ACLK266 clock for ISP - ACLK200 clock for FSYS - ACLK160 clock for LCD0 - ACLK100 clock for PERIL - GDL clock for LEFTBUS - GDR clock for RIGHTBUS - SCLK_MFC clock for MFC Signed-off-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos3250.dtsi | 147 ++ 1 file changed, 147 insertions(+) diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi index 1ae72c4fa55e..b5157492a422 100644 --- a/arch/arm/boot/dts/exynos3250.dtsi +++ b/arch/arm/boot/dts/exynos3250.dtsi @@ -722,6 +722,153 @@ opp-microvolt = <875000>; }; }; + + bus_leftbus: bus_leftbus { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_GDL>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_rightbus: bus_rightbus { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_GDR>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_lcd0: bus_lcd0 { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_ACLK_160>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_fsys: bus_fsys { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_ACLK_200>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_mcuisp: bus_mcuisp { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_ACLK_400_MCUISP>; + clock-names = "bus"; + operating-points-v2 = <_mcuisp_opp_table>; + status = "disabled"; + }; + + bus_isp: bus_isp { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_ACLK_266>; + clock-names = "bus"; + operating-points-v2 = <_isp_opp_table>; + status = "disabled"; + }; + + bus_peril: bus_peril { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_ACLK_100>; + clock-names = "bus"; + operating-points-v2 = <_peril_opp_table>; + status = "disabled"; + }; + + bus_mfc: bus_mfc { + compatible = "samsung,exynos-bus"; + clocks = < CLK_SCLK_MFC>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_leftbus_opp_table: opp_table2 { + compatible = "operating-points-v2"; + opp-shared; + + opp@5000 { + opp-hz = /bits/ 64 <5000>; + opp-microvolt = <90>; + }; + opp@8000 { + opp-hz = /bits/ 64 <8000>; + opp-microvolt = <90>; + }; + opp@1 { + opp-hz = /bits/ 64 <1>; + opp-microvolt = <100>; + }; + opp@13400 { + opp-hz = /bits/ 64 <13400>; + opp-microvolt = <100>; + }; + opp@2 { + opp-hz = /bits/ 64 <2>; + opp-microvolt = <100>; + }; + }; + + bus_mcuisp_opp_table: opp_table3 { + compatible = "operating-points-v2"; + opp-shared; + + opp@5000 { + opp-hz = /bits/ 64 <5000>; + }; +
[PATCH v5 15/21] ARM: dts: Add bus nodes using VDD_MIF for Exynos4x12
This patch adds the bus nodes using VDD_MIF for Exynos4x12 SoC. Exynos4x12 has the following AXI buses to translate data between DRAM and DMC/ACP/C2C. Signed-off-by: Chanwoo ChoiReviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos4x12.dtsi | 68 +++ 1 file changed, 68 insertions(+) diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi index 84a23f962946..99a0f4ca3d47 100644 --- a/arch/arm/boot/dts/exynos4x12.dtsi +++ b/arch/arm/boot/dts/exynos4x12.dtsi @@ -281,6 +281,74 @@ clocks = < CLK_SMMU_LITE1>, < CLK_FIMC_LITE1>; #iommu-cells = <0>; }; + + bus_dmc: bus_dmc { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_DMC>; + clock-names = "bus"; + operating-points-v2 = <_dmc_opp_table>; + status = "disabled"; + }; + + bus_acp: bus_acp { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_ACP>; + clock-names = "bus"; + operating-points-v2 = <_acp_opp_table>; + status = "disabled"; + }; + + bus_c2c: bus_c2c { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_C2C>; + clock-names = "bus"; + operating-points-v2 = <_dmc_opp_table>; + status = "disabled"; + }; + + bus_dmc_opp_table: opp_table1 { + compatible = "operating-points-v2"; + opp-shared; + + opp@1 { + opp-hz = /bits/ 64 <1>; + opp-microvolt = <90>; + }; + opp@13400 { + opp-hz = /bits/ 64 <13400>; + opp-microvolt = <90>; + }; + opp@16000 { + opp-hz = /bits/ 64 <16000>; + opp-microvolt = <90>; + }; + opp@26700 { + opp-hz = /bits/ 64 <26700>; + opp-microvolt = <95>; + }; + opp@4 { + opp-hz = /bits/ 64 <4>; + opp-microvolt = <105>; + }; + }; + + bus_acp_opp_table: opp_table2 { + compatible = "operating-points-v2"; + opp-shared; + + opp@1 { + opp-hz = /bits/ 64 <1>; + }; + opp@13400 { + opp-hz = /bits/ 64 <13400>; + }; + opp@16000 { + opp-hz = /bits/ 64 <16000>; + }; + opp@26700 { + opp-hz = /bits/ 64 <26700>; + }; + }; }; { -- 1.9.1
[PATCH v5 15/21] ARM: dts: Add bus nodes using VDD_MIF for Exynos4x12
This patch adds the bus nodes using VDD_MIF for Exynos4x12 SoC. Exynos4x12 has the following AXI buses to translate data between DRAM and DMC/ACP/C2C. Signed-off-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos4x12.dtsi | 68 +++ 1 file changed, 68 insertions(+) diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi index 84a23f962946..99a0f4ca3d47 100644 --- a/arch/arm/boot/dts/exynos4x12.dtsi +++ b/arch/arm/boot/dts/exynos4x12.dtsi @@ -281,6 +281,74 @@ clocks = < CLK_SMMU_LITE1>, < CLK_FIMC_LITE1>; #iommu-cells = <0>; }; + + bus_dmc: bus_dmc { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_DMC>; + clock-names = "bus"; + operating-points-v2 = <_dmc_opp_table>; + status = "disabled"; + }; + + bus_acp: bus_acp { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_ACP>; + clock-names = "bus"; + operating-points-v2 = <_acp_opp_table>; + status = "disabled"; + }; + + bus_c2c: bus_c2c { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_C2C>; + clock-names = "bus"; + operating-points-v2 = <_dmc_opp_table>; + status = "disabled"; + }; + + bus_dmc_opp_table: opp_table1 { + compatible = "operating-points-v2"; + opp-shared; + + opp@1 { + opp-hz = /bits/ 64 <1>; + opp-microvolt = <90>; + }; + opp@13400 { + opp-hz = /bits/ 64 <13400>; + opp-microvolt = <90>; + }; + opp@16000 { + opp-hz = /bits/ 64 <16000>; + opp-microvolt = <90>; + }; + opp@26700 { + opp-hz = /bits/ 64 <26700>; + opp-microvolt = <95>; + }; + opp@4 { + opp-hz = /bits/ 64 <4>; + opp-microvolt = <105>; + }; + }; + + bus_acp_opp_table: opp_table2 { + compatible = "operating-points-v2"; + opp-shared; + + opp@1 { + opp-hz = /bits/ 64 <1>; + }; + opp@13400 { + opp-hz = /bits/ 64 <13400>; + }; + opp@16000 { + opp-hz = /bits/ 64 <16000>; + }; + opp@26700 { + opp-hz = /bits/ 64 <26700>; + }; + }; }; { -- 1.9.1
[PATCH v5 00/21] PM / devferq: Add generic exynos bus frequency driver and new passive governor
Dear all, This patchset uses the DEVFREQ_TRANSITION_NOTIFIER notifier to connecth devfreq device using ondemand governor and devfreq device using passive governor. Also I fix the some issue reported by 'Tobias Jakobi' and add the detailed issue information. But, this patchset don't modify the anything of Device Tree patches (patch12 ~ patch21) which already got the reviewed-by from Exynos Soc Maintainer. I tested it on exynos3250-rinato and exynos4412-odroidu3 board. [Description] This patch-set includes the two features as following. The generic exynos bus frequency driver is able to support almost Exynos SoCs for bus frequency scaling. And the new passive governor is able to make the dependency on between devices for frequency/voltage scaling. I had posted the patch-set[1] with the similiar concept. This is is revised version for exynos bus frequency. - Generic exynos bus frequency driver - New passive governor of DEVFREQ framework [1] https://lkml.org/lkml/2015/1/7/872 : [PATCHv3 0/8] devfreq: Add generic exynos memory-bus frequency driver Changes from v4: (https://lkml.org/lkml/2015/12/14/43) - Add new DEVFREQ_TRANSITION_NOTIFIER notifier. The passive devfreq device recevie the changed frequency of parent devfreq device through DEVFREQ_TRANSITION_NOTIFIER. - Add governor type to identify thme using the defined constant - Modify the passive governor using the DEVFREQ_TRANSITION_NOTIFIER notifier. - Fix the RCU locking probrlm (Reported-by: Tobias Jakobi) - Fix the debugfs error during the kernel booting (Reported-by: Tobias Jakobi) Changes from v3: (https://lkml.org/lkml/2015/12/11/75) - Add the reviewed-by tag from Krzysztof Kozlowski (patch2/3/13/14/15/16/17) - Fix typo of the description on patch14 - Modify the subject and description of patch17 - Reorder the 'bus_xxx' device tree node alphabetically in both exynos3250-rinato/monk.dts and exynos4412-trats/odroidu3 Changes from v2: (https://lkml.org/lkml/2015/12/8/869) - Fix typo on documentation - Modify the more appropriate sentence on patch description - Add the detailed description about both parent and passive bus device - Modify the DMC frequency for Exynos4x12 DMC bus (200MHz -> 267MHz) - Modify the voltage of 200MHz was included in Exynos3250 DMC bus (800mV -> 825mV) - Rename OPP nodes as 'opp@' - Delete the duplicate 'opp-microvolt' property of passive devfreq device - Reorder the 'bus_xxx' device tree node alphabetically in exynos3250-rinato/monk.dts - Reorder the 'bus_xxx' device tree node alphabetically in exynos4412-trats/odroidu3 - Add new exynos4412-ppmu-common.dtsi to remove the duplicate PPMU dt node on rinato/monk/trats2/odroid-u3 board - Add the log message if bus device is registered to devfreq framework successfully - Add the reviewed-by tag from Krzysztof Kozlowski - Add the tested-by tag from Anand Moon on Odroid U3 - Add 'SAMSUNG BUS FREQUENCY DRIVER' entry to MAINTAINERS Changes from v1: (https://lkml.org/lkml/2015/11/26/260) - Check whether the instance of regulator is NULL or not when executing regulator_disable() because of only parent devfreq device has the regulator instance. After fixing it, the wake-up from suspend state is well working. (patch1) - Fix bug which checks 'bus-clk' instead of 'bus->regulator' after calling devm_clk_get() (on patch1) - Update the documentation to remove the description about DEVFREQ-EVENT subsystem (on patch2) - Add the full name of DMC (Dynamic Memory Controller) (on patch2) - Modify the detailed correlation of buses for Exynos3250 on documentation (patch2) - Add the MFC bus node for Exynos3250 (on patch11, patch12) - Fix the duplicate frequency of bus_display on Exynos4x12.dtsi - Add the PPMU node for exynos4412-odroidu3 - Add the support of bus frequency for exynos4412-odroidu3 Detailed descirption for patch-set: 1. Add generic exynos bus frequency driver : This patch-set adds the generic exynos bus frequency driver for AXI bus of sub-blocks in exynos SoC. The Samsung Exynos SoC have the common architecture for bus between DRAM and sub-blocks in SoC. There are the different buses according to Exynos SoC because Exynos SoC has the differnt sub-blocks and bus speed. In spite of this difference among Exynos SoCs, this driver is able to support almost Exynos SoC by adding unique data of each bus in the devicetree file. In devicetree, each bus node has a bus clock, regulator, operation-point and devfreq-event devices which measure the utilization of each bus block. For example, - The bus of DMC block in exynos3250.dtsi are listed below: bus_dmc: bus_dmc { compatible = "samsung,exynos-bus"; clocks = <_dmc CLK_DIV_DMC>; clock-names = "bus"; operating-points-v2 = <_dmc_opp_table>; status = "disabled"; }; bus_dmc_opp_table: opp_table1 { compatible = "operating-points-v2"; opp-shared; opp@5000 {
[PATCH v5 16/21] ARM: dts: Add bus nodes using VDD_INT for Exynos4x12
This patch adds the bus nodes using VDD_INT for Exynos4x12 SoC. Exynos4x12 has the following AXI buses to translate data between DRAM and sub-blocks. Following list specifies the detailed relation between DRAM and sub-blocks: - ACLK100 clock for PERIL/PERIR/MFC(PCLK) - ACLK160 clock for CAM/TV/LCD : The minimum clock of ACLK160 should be over 160MHz. When drop the clock under 160MHz, show the broken image. - ACLK133 clock for FSYS - GDL clock for LEFTBUS - GDR clock for RIGHTBUS - SCLK_MFC clock for MFC Signed-off-by: Chanwoo ChoiReviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos4x12.dtsi | 106 ++ 1 file changed, 106 insertions(+) diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi index 99a0f4ca3d47..e5173107ed44 100644 --- a/arch/arm/boot/dts/exynos4x12.dtsi +++ b/arch/arm/boot/dts/exynos4x12.dtsi @@ -349,6 +349,112 @@ opp-hz = /bits/ 64 <26700>; }; }; + + bus_leftbus: bus_leftbus { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_GDL>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_rightbus: bus_rightbus { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_GDR>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_display: bus_display { + compatible = "samsung,exynos-bus"; + clocks = < CLK_ACLK160>; + clock-names = "bus"; + operating-points-v2 = <_display_opp_table>; + status = "disabled"; + }; + + bus_fsys: bus_fsys { + compatible = "samsung,exynos-bus"; + clocks = < CLK_ACLK133>; + clock-names = "bus"; + operating-points-v2 = <_fsys_opp_table>; + status = "disabled"; + }; + + bus_peri: bus_peri { + compatible = "samsung,exynos-bus"; + clocks = < CLK_ACLK100>; + clock-names = "bus"; + operating-points-v2 = <_peri_opp_table>; + status = "disabled"; + }; + + bus_mfc: bus_mfc { + compatible = "samsung,exynos-bus"; + clocks = < CLK_SCLK_MFC>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_leftbus_opp_table: opp_table3 { + compatible = "operating-points-v2"; + opp-shared; + + opp@1 { + opp-hz = /bits/ 64 <1>; + opp-microvolt = <90>; + }; + opp@13400 { + opp-hz = /bits/ 64 <13400>; + opp-microvolt = <925000>; + }; + opp@16000 { + opp-hz = /bits/ 64 <16000>; + opp-microvolt = <95>; + }; + opp@2 { + opp-hz = /bits/ 64 <2>; + opp-microvolt = <100>; + }; + }; + + bus_display_opp_table: opp_table4 { + compatible = "operating-points-v2"; + opp-shared; + + opp@16000 { + opp-hz = /bits/ 64 <16000>; + }; + opp@2 { + opp-hz = /bits/ 64 <2>; + }; + }; + + bus_fsys_opp_table: opp_table5 { + compatible = "operating-points-v2"; + opp-shared; + + opp@1 { + opp-hz = /bits/ 64 <1>; + }; + opp@13400 { + opp-hz = /bits/ 64 <13400>; + }; + }; + + bus_peri_opp_table: opp_table6 { + compatible = "operating-points-v2"; + opp-shared; + + opp@5000 { + opp-hz = /bits/ 64 <5000>; + }; + opp@1 { + opp-hz = /bits/ 64 <1>; + }; + }; }; { -- 1.9.1
[PATCH v5 00/21] PM / devferq: Add generic exynos bus frequency driver and new passive governor
Dear all, This patchset uses the DEVFREQ_TRANSITION_NOTIFIER notifier to connecth devfreq device using ondemand governor and devfreq device using passive governor. Also I fix the some issue reported by 'Tobias Jakobi' and add the detailed issue information. But, this patchset don't modify the anything of Device Tree patches (patch12 ~ patch21) which already got the reviewed-by from Exynos Soc Maintainer. I tested it on exynos3250-rinato and exynos4412-odroidu3 board. [Description] This patch-set includes the two features as following. The generic exynos bus frequency driver is able to support almost Exynos SoCs for bus frequency scaling. And the new passive governor is able to make the dependency on between devices for frequency/voltage scaling. I had posted the patch-set[1] with the similiar concept. This is is revised version for exynos bus frequency. - Generic exynos bus frequency driver - New passive governor of DEVFREQ framework [1] https://lkml.org/lkml/2015/1/7/872 : [PATCHv3 0/8] devfreq: Add generic exynos memory-bus frequency driver Changes from v4: (https://lkml.org/lkml/2015/12/14/43) - Add new DEVFREQ_TRANSITION_NOTIFIER notifier. The passive devfreq device recevie the changed frequency of parent devfreq device through DEVFREQ_TRANSITION_NOTIFIER. - Add governor type to identify thme using the defined constant - Modify the passive governor using the DEVFREQ_TRANSITION_NOTIFIER notifier. - Fix the RCU locking probrlm (Reported-by: Tobias Jakobi) - Fix the debugfs error during the kernel booting (Reported-by: Tobias Jakobi) Changes from v3: (https://lkml.org/lkml/2015/12/11/75) - Add the reviewed-by tag from Krzysztof Kozlowski (patch2/3/13/14/15/16/17) - Fix typo of the description on patch14 - Modify the subject and description of patch17 - Reorder the 'bus_xxx' device tree node alphabetically in both exynos3250-rinato/monk.dts and exynos4412-trats/odroidu3 Changes from v2: (https://lkml.org/lkml/2015/12/8/869) - Fix typo on documentation - Modify the more appropriate sentence on patch description - Add the detailed description about both parent and passive bus device - Modify the DMC frequency for Exynos4x12 DMC bus (200MHz -> 267MHz) - Modify the voltage of 200MHz was included in Exynos3250 DMC bus (800mV -> 825mV) - Rename OPP nodes as 'opp@' - Delete the duplicate 'opp-microvolt' property of passive devfreq device - Reorder the 'bus_xxx' device tree node alphabetically in exynos3250-rinato/monk.dts - Reorder the 'bus_xxx' device tree node alphabetically in exynos4412-trats/odroidu3 - Add new exynos4412-ppmu-common.dtsi to remove the duplicate PPMU dt node on rinato/monk/trats2/odroid-u3 board - Add the log message if bus device is registered to devfreq framework successfully - Add the reviewed-by tag from Krzysztof Kozlowski - Add the tested-by tag from Anand Moon on Odroid U3 - Add 'SAMSUNG BUS FREQUENCY DRIVER' entry to MAINTAINERS Changes from v1: (https://lkml.org/lkml/2015/11/26/260) - Check whether the instance of regulator is NULL or not when executing regulator_disable() because of only parent devfreq device has the regulator instance. After fixing it, the wake-up from suspend state is well working. (patch1) - Fix bug which checks 'bus-clk' instead of 'bus->regulator' after calling devm_clk_get() (on patch1) - Update the documentation to remove the description about DEVFREQ-EVENT subsystem (on patch2) - Add the full name of DMC (Dynamic Memory Controller) (on patch2) - Modify the detailed correlation of buses for Exynos3250 on documentation (patch2) - Add the MFC bus node for Exynos3250 (on patch11, patch12) - Fix the duplicate frequency of bus_display on Exynos4x12.dtsi - Add the PPMU node for exynos4412-odroidu3 - Add the support of bus frequency for exynos4412-odroidu3 Detailed descirption for patch-set: 1. Add generic exynos bus frequency driver : This patch-set adds the generic exynos bus frequency driver for AXI bus of sub-blocks in exynos SoC. The Samsung Exynos SoC have the common architecture for bus between DRAM and sub-blocks in SoC. There are the different buses according to Exynos SoC because Exynos SoC has the differnt sub-blocks and bus speed. In spite of this difference among Exynos SoCs, this driver is able to support almost Exynos SoC by adding unique data of each bus in the devicetree file. In devicetree, each bus node has a bus clock, regulator, operation-point and devfreq-event devices which measure the utilization of each bus block. For example, - The bus of DMC block in exynos3250.dtsi are listed below: bus_dmc: bus_dmc { compatible = "samsung,exynos-bus"; clocks = <_dmc CLK_DIV_DMC>; clock-names = "bus"; operating-points-v2 = <_dmc_opp_table>; status = "disabled"; }; bus_dmc_opp_table: opp_table1 { compatible = "operating-points-v2"; opp-shared; opp@5000 {
[PATCH v5 16/21] ARM: dts: Add bus nodes using VDD_INT for Exynos4x12
This patch adds the bus nodes using VDD_INT for Exynos4x12 SoC. Exynos4x12 has the following AXI buses to translate data between DRAM and sub-blocks. Following list specifies the detailed relation between DRAM and sub-blocks: - ACLK100 clock for PERIL/PERIR/MFC(PCLK) - ACLK160 clock for CAM/TV/LCD : The minimum clock of ACLK160 should be over 160MHz. When drop the clock under 160MHz, show the broken image. - ACLK133 clock for FSYS - GDL clock for LEFTBUS - GDR clock for RIGHTBUS - SCLK_MFC clock for MFC Signed-off-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos4x12.dtsi | 106 ++ 1 file changed, 106 insertions(+) diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi index 99a0f4ca3d47..e5173107ed44 100644 --- a/arch/arm/boot/dts/exynos4x12.dtsi +++ b/arch/arm/boot/dts/exynos4x12.dtsi @@ -349,6 +349,112 @@ opp-hz = /bits/ 64 <26700>; }; }; + + bus_leftbus: bus_leftbus { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_GDL>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_rightbus: bus_rightbus { + compatible = "samsung,exynos-bus"; + clocks = < CLK_DIV_GDR>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_display: bus_display { + compatible = "samsung,exynos-bus"; + clocks = < CLK_ACLK160>; + clock-names = "bus"; + operating-points-v2 = <_display_opp_table>; + status = "disabled"; + }; + + bus_fsys: bus_fsys { + compatible = "samsung,exynos-bus"; + clocks = < CLK_ACLK133>; + clock-names = "bus"; + operating-points-v2 = <_fsys_opp_table>; + status = "disabled"; + }; + + bus_peri: bus_peri { + compatible = "samsung,exynos-bus"; + clocks = < CLK_ACLK100>; + clock-names = "bus"; + operating-points-v2 = <_peri_opp_table>; + status = "disabled"; + }; + + bus_mfc: bus_mfc { + compatible = "samsung,exynos-bus"; + clocks = < CLK_SCLK_MFC>; + clock-names = "bus"; + operating-points-v2 = <_leftbus_opp_table>; + status = "disabled"; + }; + + bus_leftbus_opp_table: opp_table3 { + compatible = "operating-points-v2"; + opp-shared; + + opp@1 { + opp-hz = /bits/ 64 <1>; + opp-microvolt = <90>; + }; + opp@13400 { + opp-hz = /bits/ 64 <13400>; + opp-microvolt = <925000>; + }; + opp@16000 { + opp-hz = /bits/ 64 <16000>; + opp-microvolt = <95>; + }; + opp@2 { + opp-hz = /bits/ 64 <2>; + opp-microvolt = <100>; + }; + }; + + bus_display_opp_table: opp_table4 { + compatible = "operating-points-v2"; + opp-shared; + + opp@16000 { + opp-hz = /bits/ 64 <16000>; + }; + opp@2 { + opp-hz = /bits/ 64 <2>; + }; + }; + + bus_fsys_opp_table: opp_table5 { + compatible = "operating-points-v2"; + opp-shared; + + opp@1 { + opp-hz = /bits/ 64 <1>; + }; + opp@13400 { + opp-hz = /bits/ 64 <13400>; + }; + }; + + bus_peri_opp_table: opp_table6 { + compatible = "operating-points-v2"; + opp-shared; + + opp@5000 { + opp-hz = /bits/ 64 <5000>; + }; + opp@1 { + opp-hz = /bits/ 64 <1>; + }; + }; }; { -- 1.9.1
[PATCH v5 18/21] ARM: dts: Add exynos4412-ppmu-common dtsi to delete duplicate PPMU nodes
This patch adds the exynos4412-ppmu-common.dtsi to remove duplicate PPMU nodes because exynos3250-rinato/monk, exynos4412-trats2/odroidu3 has the same PPMU device tree node. Signed-off-by: Chanwoo ChoiReviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos3250-monk.dts | 41 +--- arch/arm/boot/dts/exynos3250-rinato.dts | 41 +--- arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 1 + arch/arm/boot/dts/exynos4412-ppmu-common.dtsi | 50 + arch/arm/boot/dts/exynos4412-trats2.dts | 41 +--- 5 files changed, 54 insertions(+), 120 deletions(-) create mode 100644 arch/arm/boot/dts/exynos4412-ppmu-common.dtsi diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts index 1fd7ecb5c415..fbe09d640c9a 100644 --- a/arch/arm/boot/dts/exynos3250-monk.dts +++ b/arch/arm/boot/dts/exynos3250-monk.dts @@ -14,6 +14,7 @@ /dts-v1/; #include "exynos3250.dtsi" +#include "exynos4412-ppmu-common.dtsi" #include #include #include @@ -464,46 +465,6 @@ status = "okay"; }; -_dmc0 { - status = "okay"; - - events { - ppmu_dmc0_3: ppmu-event3-dmc0 { - event-name = "ppmu-event3-dmc0"; - }; - }; -}; - -_dmc1 { - status = "okay"; - - events { - ppmu_dmc1_3: ppmu-event3-dmc1 { - event-name = "ppmu-event3-dmc1"; - }; - }; -}; - -_leftbus { - status = "okay"; - - events { - ppmu_leftbus_3: ppmu-event3-leftbus { - event-name = "ppmu-event3-leftbus"; - }; - }; -}; - -_rightbus { - status = "okay"; - - events { - ppmu_rightbus_3: ppmu-event3-rightbus { - event-name = "ppmu-event3-rightbus"; - }; - }; -}; - { clock-frequency = <2400>; }; diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts index 5175bd7e015f..9710e79e10a0 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts +++ b/arch/arm/boot/dts/exynos3250-rinato.dts @@ -14,6 +14,7 @@ /dts-v1/; #include "exynos3250.dtsi" +#include "exynos4412-ppmu-common.dtsi" #include #include #include @@ -641,46 +642,6 @@ status = "okay"; }; -_dmc0 { - status = "okay"; - - events { - ppmu_dmc0_3: ppmu-event3-dmc0 { - event-name = "ppmu-event3-dmc0"; - }; - }; -}; - -_dmc1 { - status = "okay"; - - events { - ppmu_dmc1_3: ppmu-event3-dmc1 { - event-name = "ppmu-event3-dmc1"; - }; - }; -}; - -_leftbus { - status = "okay"; - - events { - ppmu_leftbus_3: ppmu-event3-leftbus { - event-name = "ppmu-event3-leftbus"; - }; - }; -}; - -_rightbus { - status = "okay"; - - events { - ppmu_rightbus_3: ppmu-event3-rightbus { - event-name = "ppmu-event3-rightbus"; - }; - }; -}; - { clock-frequency = <2400>; }; diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index 5e5d3fecb04c..cba37c974703 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -11,6 +11,7 @@ #include #include #include "exynos4412.dtsi" +#include "exynos4412-ppmu-common.dtsi" #include / { diff --git a/arch/arm/boot/dts/exynos4412-ppmu-common.dtsi b/arch/arm/boot/dts/exynos4412-ppmu-common.dtsi new file mode 100644 index ..16e4b77d8cb1 --- /dev/null +++ b/arch/arm/boot/dts/exynos4412-ppmu-common.dtsi @@ -0,0 +1,50 @@ +/* + * Device tree sources for Exynos4412 PPMU common device tree + * + * Copyright (C) 2015 Samsung Electronics + * Author: Chanwoo Choi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +_dmc0 { + status = "okay"; + + events { + ppmu_dmc0_3: ppmu-event3-dmc0 { + event-name = "ppmu-event3-dmc0"; + }; + }; +}; + +_dmc1 { + status = "okay"; + + events { + ppmu_dmc1_3: ppmu-event3-dmc1 { + event-name = "ppmu-event3-dmc1"; + }; + }; +}; + +_leftbus { + status = "okay"; + + events { + ppmu_leftbus_3: ppmu-event3-leftbus { + event-name = "ppmu-event3-leftbus"; + }; + }; +}; + +_rightbus { + status = "okay"; + + events { + ppmu_rightbus_3: ppmu-event3-rightbus { +
[PATCH v5 19/21] ARM: dts: Add support of bus frequency using VDD_INT for exynos3250-rinato
This patch adds the bus device-tree nodes of INT (internal) block to enable the bus frequency scaling. The following sub-blocks share the VDD_INT power source: - LEFTBUS (parent device) - RIGHTBUS - PERIL - LCD0 - FSYS - MCUISP / ISP - MFC The LEFTBUS is parent device with devfreq ondemand governor and the rest of devices depend on the LEFTBUS device. Signed-off-by: Chanwoo ChoiReviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos3250-rinato.dts | 41 + 1 file changed, 41 insertions(+) diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts index 9710e79e10a0..09444897b416 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts +++ b/arch/arm/boot/dts/exynos3250-rinato.dts @@ -154,6 +154,47 @@ status = "okay"; }; +_leftbus { + devfreq-events = <_leftbus_3>, <_rightbus_3>; + vdd-supply = <_reg>; + status = "okay"; +}; + +_rightbus { + devfreq = <_leftbus>; + status = "okay"; +}; + +_lcd0 { + devfreq = <_leftbus>; + status = "okay"; +}; + +_fsys { + devfreq = <_leftbus>; + status = "okay"; +}; + +_mcuisp { + devfreq = <_leftbus>; + status = "okay"; +}; + +_isp { + devfreq = <_leftbus>; + status = "okay"; +}; + +_peril { + devfreq = <_leftbus>; + status = "okay"; +}; + +_mfc { + devfreq = <_leftbus>; + status = "okay"; +}; + { cpu0-supply = <_reg>; }; -- 1.9.1
[PATCH v5 08/21] PM / devfreq: exynos: Update documentation for bus devices using passive governor
This patch updates the documentation for passive bus devices and adds the detailed example of Exynos3250. Signed-off-by: Chanwoo Choi--- .../devicetree/bindings/devfreq/exynos-bus.txt | 250 - 1 file changed, 247 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt index 78171b918e3f..03f13d38f1a1 100644 --- a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt +++ b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt @@ -8,22 +8,46 @@ of the bus in runtime. To monitor the usage of each bus in runtime, the driver uses the PPMU (Platform Performance Monitoring Unit), which is able to measure the current load of sub-blocks. +The Exynos SoC includes the various sub-blocks which have the each AXI bus. +The each AXI bus has the owned source clock but, has not the only owned +power line. The power line might be shared among one more sub-blocks. +So, we can divide into two type of device as the role of each sub-block. +There are two type of bus devices as following: +- parent bus device +- passive bus device + +Basically, parent and passive bus device share the same power line. +The parent bus device can only change the voltage of shared power line +and the rest bus devices (passive bus device) depend on the decision of +the parent bus device. If there are three blocks which share the VDD_xxx +power line, Only one block should be parent device and then the rest blocks +should depend on the parent device as passive device. + + VDD_xxx |--- A block (parent) + |--- B block (passive) + |--- C block (passive) + There are a little different composition among Exynos SoC because each Exynos SoC has different sub-blocks. Therefore, shch difference should be specified in devicetree file instead of each device driver. In result, this driver is able to support the bus frequency for all Exynos SoCs. -Required properties for bus device: +Required properties for all bus devices: - compatible: Should be "samsung,exynos-bus". - clock-names : the name of clock used by the bus, "bus". - clocks : phandles for clock specified in "clock-names" property. - operating-points-v2: the OPP table including frequency/voltage information to support DVFS (Dynamic Voltage/Frequency Scaling) feature. + +Required properties only for parent bus device: - vdd-supply: the regulator to provide the buses with the voltage. - devfreq-events: the devfreq-event device to monitor the current utilization of buses. -Optional properties for bus device: +Required properties only for passive bus device: +- devfreq: the parent bus device. + +Optional properties only for parent bus device: - exynos,saturation-ratio: the percentage value which is used to calibrate the performance count against total cycle count. - exynos,voltage-tolerance: the percentage value for bus voltage tolerance @@ -34,7 +58,20 @@ Example1: power line (regulator). The MIF (Memory Interface) AXI bus is used to transfer data between DRAM and CPU and uses the VDD_MIF regualtor. - - power line(VDD_MIF) --> bus for DMC (Dynamic Memory Controller) block + - MIF (Memory Interface) block + : VDD_MIF |--- DMC (Dynamic Memory Controller) + + - INT (Internal) block + : VDD_INT |--- LEFTBUS (parent device) + |--- PERIL + |--- MFC + |--- G3D + |--- RIGHTBUS + |--- FSYS + |--- LCD0 + |--- PERIR + |--- ISP + |--- CAM - MIF bus's frequency/voltage table --- @@ -47,6 +84,24 @@ Example1: |L5| 40 |875000 | --- + - INT bus's frequency/voltage table + -- + |Block|LEFTBUS|RIGHTBUS|MCUISP |ISP|PERIL ||VDD_INT | + | name| |LCD0| | | ||| + | | |FSYS| | | ||| + | | |MFC | | | ||| + -- + |Mode |*parent|passive |passive|passive|passive||| + -- + |Lv |Frequency ||Voltage | + -- + |L1 |5 |5 |5 |5 |5 ||90 | + |L2 |8 |8 |8 |8 |8 ||90 | + |L3 |10 |10 |10 |10 |10 ||100 | + |L4 |134000 |134000 |20 |20 | ||100 | + |L5 |20 |20 |40 |30 | ||100 | +
[PATCH v5 19/21] ARM: dts: Add support of bus frequency using VDD_INT for exynos3250-rinato
This patch adds the bus device-tree nodes of INT (internal) block to enable the bus frequency scaling. The following sub-blocks share the VDD_INT power source: - LEFTBUS (parent device) - RIGHTBUS - PERIL - LCD0 - FSYS - MCUISP / ISP - MFC The LEFTBUS is parent device with devfreq ondemand governor and the rest of devices depend on the LEFTBUS device. Signed-off-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos3250-rinato.dts | 41 + 1 file changed, 41 insertions(+) diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts index 9710e79e10a0..09444897b416 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts +++ b/arch/arm/boot/dts/exynos3250-rinato.dts @@ -154,6 +154,47 @@ status = "okay"; }; +_leftbus { + devfreq-events = <_leftbus_3>, <_rightbus_3>; + vdd-supply = <_reg>; + status = "okay"; +}; + +_rightbus { + devfreq = <_leftbus>; + status = "okay"; +}; + +_lcd0 { + devfreq = <_leftbus>; + status = "okay"; +}; + +_fsys { + devfreq = <_leftbus>; + status = "okay"; +}; + +_mcuisp { + devfreq = <_leftbus>; + status = "okay"; +}; + +_isp { + devfreq = <_leftbus>; + status = "okay"; +}; + +_peril { + devfreq = <_leftbus>; + status = "okay"; +}; + +_mfc { + devfreq = <_leftbus>; + status = "okay"; +}; + { cpu0-supply = <_reg>; }; -- 1.9.1
[PATCH v5 08/21] PM / devfreq: exynos: Update documentation for bus devices using passive governor
This patch updates the documentation for passive bus devices and adds the detailed example of Exynos3250. Signed-off-by: Chanwoo Choi --- .../devicetree/bindings/devfreq/exynos-bus.txt | 250 - 1 file changed, 247 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt index 78171b918e3f..03f13d38f1a1 100644 --- a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt +++ b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt @@ -8,22 +8,46 @@ of the bus in runtime. To monitor the usage of each bus in runtime, the driver uses the PPMU (Platform Performance Monitoring Unit), which is able to measure the current load of sub-blocks. +The Exynos SoC includes the various sub-blocks which have the each AXI bus. +The each AXI bus has the owned source clock but, has not the only owned +power line. The power line might be shared among one more sub-blocks. +So, we can divide into two type of device as the role of each sub-block. +There are two type of bus devices as following: +- parent bus device +- passive bus device + +Basically, parent and passive bus device share the same power line. +The parent bus device can only change the voltage of shared power line +and the rest bus devices (passive bus device) depend on the decision of +the parent bus device. If there are three blocks which share the VDD_xxx +power line, Only one block should be parent device and then the rest blocks +should depend on the parent device as passive device. + + VDD_xxx |--- A block (parent) + |--- B block (passive) + |--- C block (passive) + There are a little different composition among Exynos SoC because each Exynos SoC has different sub-blocks. Therefore, shch difference should be specified in devicetree file instead of each device driver. In result, this driver is able to support the bus frequency for all Exynos SoCs. -Required properties for bus device: +Required properties for all bus devices: - compatible: Should be "samsung,exynos-bus". - clock-names : the name of clock used by the bus, "bus". - clocks : phandles for clock specified in "clock-names" property. - operating-points-v2: the OPP table including frequency/voltage information to support DVFS (Dynamic Voltage/Frequency Scaling) feature. + +Required properties only for parent bus device: - vdd-supply: the regulator to provide the buses with the voltage. - devfreq-events: the devfreq-event device to monitor the current utilization of buses. -Optional properties for bus device: +Required properties only for passive bus device: +- devfreq: the parent bus device. + +Optional properties only for parent bus device: - exynos,saturation-ratio: the percentage value which is used to calibrate the performance count against total cycle count. - exynos,voltage-tolerance: the percentage value for bus voltage tolerance @@ -34,7 +58,20 @@ Example1: power line (regulator). The MIF (Memory Interface) AXI bus is used to transfer data between DRAM and CPU and uses the VDD_MIF regualtor. - - power line(VDD_MIF) --> bus for DMC (Dynamic Memory Controller) block + - MIF (Memory Interface) block + : VDD_MIF |--- DMC (Dynamic Memory Controller) + + - INT (Internal) block + : VDD_INT |--- LEFTBUS (parent device) + |--- PERIL + |--- MFC + |--- G3D + |--- RIGHTBUS + |--- FSYS + |--- LCD0 + |--- PERIR + |--- ISP + |--- CAM - MIF bus's frequency/voltage table --- @@ -47,6 +84,24 @@ Example1: |L5| 40 |875000 | --- + - INT bus's frequency/voltage table + -- + |Block|LEFTBUS|RIGHTBUS|MCUISP |ISP|PERIL ||VDD_INT | + | name| |LCD0| | | ||| + | | |FSYS| | | ||| + | | |MFC | | | ||| + -- + |Mode |*parent|passive |passive|passive|passive||| + -- + |Lv |Frequency ||Voltage | + -- + |L1 |5 |5 |5 |5 |5 ||90 | + |L2 |8 |8 |8 |8 |8 ||90 | + |L3 |10 |10 |10 |10 |10 ||100 | + |L4 |134000 |134000 |20 |20 | ||100 | + |L5 |20 |20 |40 |30 | ||100 | + -- +
[PATCH v5 18/21] ARM: dts: Add exynos4412-ppmu-common dtsi to delete duplicate PPMU nodes
This patch adds the exynos4412-ppmu-common.dtsi to remove duplicate PPMU nodes because exynos3250-rinato/monk, exynos4412-trats2/odroidu3 has the same PPMU device tree node. Signed-off-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos3250-monk.dts | 41 +--- arch/arm/boot/dts/exynos3250-rinato.dts | 41 +--- arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 1 + arch/arm/boot/dts/exynos4412-ppmu-common.dtsi | 50 + arch/arm/boot/dts/exynos4412-trats2.dts | 41 +--- 5 files changed, 54 insertions(+), 120 deletions(-) create mode 100644 arch/arm/boot/dts/exynos4412-ppmu-common.dtsi diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts index 1fd7ecb5c415..fbe09d640c9a 100644 --- a/arch/arm/boot/dts/exynos3250-monk.dts +++ b/arch/arm/boot/dts/exynos3250-monk.dts @@ -14,6 +14,7 @@ /dts-v1/; #include "exynos3250.dtsi" +#include "exynos4412-ppmu-common.dtsi" #include #include #include @@ -464,46 +465,6 @@ status = "okay"; }; -_dmc0 { - status = "okay"; - - events { - ppmu_dmc0_3: ppmu-event3-dmc0 { - event-name = "ppmu-event3-dmc0"; - }; - }; -}; - -_dmc1 { - status = "okay"; - - events { - ppmu_dmc1_3: ppmu-event3-dmc1 { - event-name = "ppmu-event3-dmc1"; - }; - }; -}; - -_leftbus { - status = "okay"; - - events { - ppmu_leftbus_3: ppmu-event3-leftbus { - event-name = "ppmu-event3-leftbus"; - }; - }; -}; - -_rightbus { - status = "okay"; - - events { - ppmu_rightbus_3: ppmu-event3-rightbus { - event-name = "ppmu-event3-rightbus"; - }; - }; -}; - { clock-frequency = <2400>; }; diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts index 5175bd7e015f..9710e79e10a0 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts +++ b/arch/arm/boot/dts/exynos3250-rinato.dts @@ -14,6 +14,7 @@ /dts-v1/; #include "exynos3250.dtsi" +#include "exynos4412-ppmu-common.dtsi" #include #include #include @@ -641,46 +642,6 @@ status = "okay"; }; -_dmc0 { - status = "okay"; - - events { - ppmu_dmc0_3: ppmu-event3-dmc0 { - event-name = "ppmu-event3-dmc0"; - }; - }; -}; - -_dmc1 { - status = "okay"; - - events { - ppmu_dmc1_3: ppmu-event3-dmc1 { - event-name = "ppmu-event3-dmc1"; - }; - }; -}; - -_leftbus { - status = "okay"; - - events { - ppmu_leftbus_3: ppmu-event3-leftbus { - event-name = "ppmu-event3-leftbus"; - }; - }; -}; - -_rightbus { - status = "okay"; - - events { - ppmu_rightbus_3: ppmu-event3-rightbus { - event-name = "ppmu-event3-rightbus"; - }; - }; -}; - { clock-frequency = <2400>; }; diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index 5e5d3fecb04c..cba37c974703 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -11,6 +11,7 @@ #include #include #include "exynos4412.dtsi" +#include "exynos4412-ppmu-common.dtsi" #include / { diff --git a/arch/arm/boot/dts/exynos4412-ppmu-common.dtsi b/arch/arm/boot/dts/exynos4412-ppmu-common.dtsi new file mode 100644 index ..16e4b77d8cb1 --- /dev/null +++ b/arch/arm/boot/dts/exynos4412-ppmu-common.dtsi @@ -0,0 +1,50 @@ +/* + * Device tree sources for Exynos4412 PPMU common device tree + * + * Copyright (C) 2015 Samsung Electronics + * Author: Chanwoo Choi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +_dmc0 { + status = "okay"; + + events { + ppmu_dmc0_3: ppmu-event3-dmc0 { + event-name = "ppmu-event3-dmc0"; + }; + }; +}; + +_dmc1 { + status = "okay"; + + events { + ppmu_dmc1_3: ppmu-event3-dmc1 { + event-name = "ppmu-event3-dmc1"; + }; + }; +}; + +_leftbus { + status = "okay"; + + events { + ppmu_leftbus_3: ppmu-event3-leftbus { + event-name = "ppmu-event3-leftbus"; + }; + }; +}; + +_rightbus { + status = "okay"; + + events { + ppmu_rightbus_3: ppmu-event3-rightbus { + event-name = "ppmu-event3-rightbus"; + }; + };
[PATCH v5 20/21] ARM: dts: Expand the voltage range of buck1/3 regulator for exynos4412-odroidu3
This patch expands the voltage range of buck1/3 regulator due to as following: - MIF (Memory Interface) bus frequency needs the range of '900 - 1100 mV'. - INT (Internal) bus frequency needs the range of '900 - 1050 mV'. Signed-off-by: Chanwoo ChoiReviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index cba37c974703..b4983cbc4f8c 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -356,8 +356,8 @@ buck1_reg: BUCK1 { regulator-name = "vdd_mif"; - regulator-min-microvolt = <100>; - regulator-max-microvolt = <100>; + regulator-min-microvolt = <90>; + regulator-max-microvolt = <110>; regulator-always-on; regulator-boot-on; }; @@ -372,8 +372,8 @@ buck3_reg: BUCK3 { regulator-name = "vdd_int"; - regulator-min-microvolt = <100>; - regulator-max-microvolt = <100>; + regulator-min-microvolt = <90>; + regulator-max-microvolt = <105>; regulator-always-on; regulator-boot-on; }; -- 1.9.1
[PATCH v5 20/21] ARM: dts: Expand the voltage range of buck1/3 regulator for exynos4412-odroidu3
This patch expands the voltage range of buck1/3 regulator due to as following: - MIF (Memory Interface) bus frequency needs the range of '900 - 1100 mV'. - INT (Internal) bus frequency needs the range of '900 - 1050 mV'. Signed-off-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski --- arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index cba37c974703..b4983cbc4f8c 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -356,8 +356,8 @@ buck1_reg: BUCK1 { regulator-name = "vdd_mif"; - regulator-min-microvolt = <100>; - regulator-max-microvolt = <100>; + regulator-min-microvolt = <90>; + regulator-max-microvolt = <110>; regulator-always-on; regulator-boot-on; }; @@ -372,8 +372,8 @@ buck3_reg: BUCK3 { regulator-name = "vdd_int"; - regulator-min-microvolt = <100>; - regulator-max-microvolt = <100>; + regulator-min-microvolt = <90>; + regulator-max-microvolt = <105>; regulator-always-on; regulator-boot-on; }; -- 1.9.1
[PATCH v5 10/21] PM / devfreq: exynos: Remove unused exynos4/5 busfreq driver
This patch removes the unused exynos4/5 busfreq driver. Instead, generic exynos-bus frequency driver support the all Exynos SoCs. Signed-off-by: Chanwoo Choi--- drivers/devfreq/Kconfig | 22 - drivers/devfreq/Makefile |2 - drivers/devfreq/exynos/Makefile |3 - drivers/devfreq/exynos/exynos4_bus.c | 1055 -- drivers/devfreq/exynos/exynos4_bus.h | 110 drivers/devfreq/exynos/exynos5_bus.c | 431 -- drivers/devfreq/exynos/exynos_ppmu.c | 119 drivers/devfreq/exynos/exynos_ppmu.h | 86 --- 8 files changed, 1828 deletions(-) delete mode 100644 drivers/devfreq/exynos/Makefile delete mode 100644 drivers/devfreq/exynos/exynos4_bus.c delete mode 100644 drivers/devfreq/exynos/exynos4_bus.h delete mode 100644 drivers/devfreq/exynos/exynos5_bus.c delete mode 100644 drivers/devfreq/exynos/exynos_ppmu.c delete mode 100644 drivers/devfreq/exynos/exynos_ppmu.h diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 357b548851a3..48aa411d19b1 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -89,28 +89,6 @@ config ARM_EXYNOS_BUS_DEVFREQ and adjusts the operating frequencies and voltages with OPP support. This does not yet operate with optimal voltages. -config ARM_EXYNOS4_BUS_DEVFREQ - bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver" - depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM - select DEVFREQ_GOV_SIMPLE_ONDEMAND - select PM_OPP - help - This adds the DEVFREQ driver for Exynos4210 memory bus (vdd_int) - and Exynos4212/4412 memory interface and bus (vdd_mif + vdd_int). - It reads PPMU counters of memory controllers and adjusts - the operating frequencies and voltages with OPP support. - This does not yet operate with optimal voltages. - -config ARM_EXYNOS5_BUS_DEVFREQ - tristate "ARM Exynos5250 Bus DEVFREQ Driver" - depends on SOC_EXYNOS5250 - select DEVFREQ_GOV_SIMPLE_ONDEMAND - select PM_OPP - help - This adds the DEVFREQ driver for Exynos5250 bus interface (vdd_int). - It reads PPMU counters of memory controllers and adjusts the - operating frequencies and voltages with OPP support. - config ARM_TEGRA_DEVFREQ tristate "Tegra DEVFREQ Driver" depends on ARCH_TEGRA_124_SOC diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile index 2633087d5c63..09f11d9d40d5 100644 --- a/drivers/devfreq/Makefile +++ b/drivers/devfreq/Makefile @@ -8,8 +8,6 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE) += governor_passive.o # DEVFREQ Drivers obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o -obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos/ -obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ) += exynos/ obj-$(CONFIG_ARM_TEGRA_DEVFREQ)+= tegra-devfreq.o # DEVFREQ Event Drivers diff --git a/drivers/devfreq/exynos/Makefile b/drivers/devfreq/exynos/Makefile deleted file mode 100644 index 49bc9175f923.. --- a/drivers/devfreq/exynos/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# Exynos DEVFREQ Drivers -obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos_ppmu.o exynos4_bus.o -obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ) += exynos_ppmu.o exynos5_bus.o diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c deleted file mode 100644 index da9509205169.. --- a/drivers/devfreq/exynos/exynos4_bus.c +++ /dev/null @@ -1,1055 +0,0 @@ -/* drivers/devfreq/exynos4210_memorybus.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * MyungJoo Ham - * - * EXYNOS4 - Memory/Bus clock frequency scaling support in DEVFREQ framework - * This version supports EXYNOS4210 only. This changes bus frequencies - * and vddint voltages. Exynos4412/4212 should be able to be supported - * with minor modifications. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "exynos_ppmu.h" -#include "exynos4_bus.h" - -#define MAX_SAFEVOLT 120 /* 1.2V */ - -enum exynos4_busf_type { - TYPE_BUSF_EXYNOS4210, - TYPE_BUSF_EXYNOS4x12, -}; - -/* Assume that the bus is saturated if the utilization is 40% */ -#define BUS_SATURATION_RATIO 40 - -enum busclk_level_idx { - LV_0 = 0, - LV_1, - LV_2, - LV_3, - LV_4, - _LV_END -}; - -enum exynos_ppmu_idx { - PPMU_DMC0, - PPMU_DMC1, - PPMU_END, -}; - -#define EX4210_LV_MAX LV_2 -#define EX4x12_LV_MAX LV_4 -#define EX4210_LV_NUM (LV_2 + 1) -#define EX4x12_LV_NUM (LV_4 + 1) -
[PATCH v5 10/21] PM / devfreq: exynos: Remove unused exynos4/5 busfreq driver
This patch removes the unused exynos4/5 busfreq driver. Instead, generic exynos-bus frequency driver support the all Exynos SoCs. Signed-off-by: Chanwoo Choi --- drivers/devfreq/Kconfig | 22 - drivers/devfreq/Makefile |2 - drivers/devfreq/exynos/Makefile |3 - drivers/devfreq/exynos/exynos4_bus.c | 1055 -- drivers/devfreq/exynos/exynos4_bus.h | 110 drivers/devfreq/exynos/exynos5_bus.c | 431 -- drivers/devfreq/exynos/exynos_ppmu.c | 119 drivers/devfreq/exynos/exynos_ppmu.h | 86 --- 8 files changed, 1828 deletions(-) delete mode 100644 drivers/devfreq/exynos/Makefile delete mode 100644 drivers/devfreq/exynos/exynos4_bus.c delete mode 100644 drivers/devfreq/exynos/exynos4_bus.h delete mode 100644 drivers/devfreq/exynos/exynos5_bus.c delete mode 100644 drivers/devfreq/exynos/exynos_ppmu.c delete mode 100644 drivers/devfreq/exynos/exynos_ppmu.h diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 357b548851a3..48aa411d19b1 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -89,28 +89,6 @@ config ARM_EXYNOS_BUS_DEVFREQ and adjusts the operating frequencies and voltages with OPP support. This does not yet operate with optimal voltages. -config ARM_EXYNOS4_BUS_DEVFREQ - bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver" - depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM - select DEVFREQ_GOV_SIMPLE_ONDEMAND - select PM_OPP - help - This adds the DEVFREQ driver for Exynos4210 memory bus (vdd_int) - and Exynos4212/4412 memory interface and bus (vdd_mif + vdd_int). - It reads PPMU counters of memory controllers and adjusts - the operating frequencies and voltages with OPP support. - This does not yet operate with optimal voltages. - -config ARM_EXYNOS5_BUS_DEVFREQ - tristate "ARM Exynos5250 Bus DEVFREQ Driver" - depends on SOC_EXYNOS5250 - select DEVFREQ_GOV_SIMPLE_ONDEMAND - select PM_OPP - help - This adds the DEVFREQ driver for Exynos5250 bus interface (vdd_int). - It reads PPMU counters of memory controllers and adjusts the - operating frequencies and voltages with OPP support. - config ARM_TEGRA_DEVFREQ tristate "Tegra DEVFREQ Driver" depends on ARCH_TEGRA_124_SOC diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile index 2633087d5c63..09f11d9d40d5 100644 --- a/drivers/devfreq/Makefile +++ b/drivers/devfreq/Makefile @@ -8,8 +8,6 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE) += governor_passive.o # DEVFREQ Drivers obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ) += exynos-bus.o -obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos/ -obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ) += exynos/ obj-$(CONFIG_ARM_TEGRA_DEVFREQ)+= tegra-devfreq.o # DEVFREQ Event Drivers diff --git a/drivers/devfreq/exynos/Makefile b/drivers/devfreq/exynos/Makefile deleted file mode 100644 index 49bc9175f923.. --- a/drivers/devfreq/exynos/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# Exynos DEVFREQ Drivers -obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos_ppmu.o exynos4_bus.o -obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ) += exynos_ppmu.o exynos5_bus.o diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c deleted file mode 100644 index da9509205169.. --- a/drivers/devfreq/exynos/exynos4_bus.c +++ /dev/null @@ -1,1055 +0,0 @@ -/* drivers/devfreq/exynos4210_memorybus.c - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * MyungJoo Ham - * - * EXYNOS4 - Memory/Bus clock frequency scaling support in DEVFREQ framework - * This version supports EXYNOS4210 only. This changes bus frequencies - * and vddint voltages. Exynos4412/4212 should be able to be supported - * with minor modifications. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "exynos_ppmu.h" -#include "exynos4_bus.h" - -#define MAX_SAFEVOLT 120 /* 1.2V */ - -enum exynos4_busf_type { - TYPE_BUSF_EXYNOS4210, - TYPE_BUSF_EXYNOS4x12, -}; - -/* Assume that the bus is saturated if the utilization is 40% */ -#define BUS_SATURATION_RATIO 40 - -enum busclk_level_idx { - LV_0 = 0, - LV_1, - LV_2, - LV_3, - LV_4, - _LV_END -}; - -enum exynos_ppmu_idx { - PPMU_DMC0, - PPMU_DMC1, - PPMU_END, -}; - -#define EX4210_LV_MAX LV_2 -#define EX4x12_LV_MAX LV_4 -#define EX4210_LV_NUM (LV_2 + 1) -#define EX4x12_LV_NUM (LV_4 + 1) - -/** - * struct busfreq_opp_info - opp
[PATCH] cpufreq: dt: Drop stale comment
The comment in file header doesn't hold true anymore, drop it. Signed-off-by: Viresh Kumar--- drivers/cpufreq/cpufreq-dt.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index f951f911786e..5f8dbe640a20 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -4,9 +4,6 @@ * Copyright (C) 2014 Linaro. * Viresh Kumar * - * The OPP code in function set_target() is reused from - * drivers/cpufreq/omap-cpufreq.c - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. -- 2.7.1.410.g6faf27b
[PATCH] cpufreq: dt: Drop stale comment
The comment in file header doesn't hold true anymore, drop it. Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq-dt.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index f951f911786e..5f8dbe640a20 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -4,9 +4,6 @@ * Copyright (C) 2014 Linaro. * Viresh Kumar * - * The OPP code in function set_target() is reused from - * drivers/cpufreq/omap-cpufreq.c - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. -- 2.7.1.410.g6faf27b
[PATCH v7] acpi: Issue _OSC call for native thermal interrupt handling
There are several reports of freeze on enabling HWP (Hardware PStates) feature on Skylake based systems by Intel P states driver. The root cause is identified as the HWP interrupts causing BIOS code to freeze. HWP interrupts uses thermal LVT. Linux natively handles thermal interrupts, but in Skylake based systems SMM will take control of thermal interrupts. This is a problem for several reasons: - It is freezing in BIOS when tries to handle thermal interrupt, which will require BIOS upgrade - With SMM handling thermal we loose all the reporting features of Linux arch/x86/kernel/cpu/mcheck/therm_throt driver - Some thermal drivers like x86-package-temp driver depends on the thermal threshold interrupts - The HWP interrupts are useful for debugging and tuning performance So we need native handling of thermal interrupts. This requires some way to inform SMM that OS can handle thermal interrupts. This can be done by using _OSC/_PDC under processor scope very early in ACPI initialization flow. The bit 12 of _OSC/_PDC in processor scope defines whether OS supports handling of native interrupts for Collaborative Processor Performance Control (CPPC) notifications. Since HWP is a implementation of CPPC, setting this bit is equivalent to inform SMM that OS is capable of handling thermal interrupts. Refer to this document for details on _OSC/_PDC http://www.intel.com/content/www/us/en/standards/processor-vendor- specific-acpi-specification.html This change introduces a new function acpi_early_processor_set_osc(), which walks acpi name space and finds acpi processor object and set capability via _OSC method. Also this change writes HWP status bits to 0 to clear any HWP status bits in intel_thermal_interrupt(). Signed-off-by: Srinivas Pandruvada--- v7: Checking platform ack and setting status for successful ack and printing information message. v6: Added __init for two functions and moved dummy function to internal.h Shortened the name of the function. v5: No code change. Changed commit message to explain HWP is a implementation of CPPC. v4: Suggestion by Boris for removing use of intermediate variable for clearing HWP status and using boot_cpu_has instead of static_cpu_has v3: - Added CONFIG_X86 around static_cpu_has() to fix compile error on ARCH=ia64, reported by kbuild test robot - return AE_CTRL_TERMINATE to terminate acpi name walk space, when _OSC is set already once. v2: Unnecessary newline was introduced, removed that in acpi_processor.c arch/x86/kernel/cpu/mcheck/therm_throt.c | 3 ++ drivers/acpi/acpi_processor.c| 52 drivers/acpi/bus.c | 3 ++ drivers/acpi/internal.h | 6 4 files changed, 64 insertions(+) diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index 0b445c2..ac780ca 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c @@ -384,6 +384,9 @@ static void intel_thermal_interrupt(void) { __u64 msr_val; + if (static_cpu_has(X86_FEATURE_HWP)) + wrmsrl_safe(MSR_HWP_STATUS, 0); + rdmsrl(MSR_IA32_THERM_STATUS, msr_val); /* Check for violation of core thermal thresholds*/ diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index b5e54f2..4239b80 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -491,6 +491,58 @@ static void acpi_processor_remove(struct acpi_device *device) } #endif /* CONFIG_ACPI_HOTPLUG_CPU */ +#ifdef CONFIG_X86 +static bool acpi_hwp_native_thermal_lvt_set; +static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle, + u32 lvl, + void *context, + void **rv) +{ + u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953"; + u32 capbuf[2]; + struct acpi_osc_context osc_context = { + .uuid_str = sb_uuid_str, + .rev = 1, + .cap.length = 8, + .cap.pointer = capbuf, + }; + + if (acpi_hwp_native_thermal_lvt_set) + return AE_CTRL_TERMINATE; + + capbuf[0] = 0x; + capbuf[1] = 0x1000; /* set bit 12 */ + + if (ACPI_SUCCESS(acpi_run_osc(handle, _context))) { + if (osc_context.ret.pointer && osc_context.ret.length > 1) { + u32 *capbuf_ret = osc_context.ret.pointer; + + if (capbuf_ret[1] & 0x1000) { + acpi_handle_info(handle, + "_OSC native thermal LVT Acked\n"); + acpi_hwp_native_thermal_lvt_set = true; + } + } + kfree(osc_context.ret.pointer); + } + +
[PATCH v7] acpi: Issue _OSC call for native thermal interrupt handling
There are several reports of freeze on enabling HWP (Hardware PStates) feature on Skylake based systems by Intel P states driver. The root cause is identified as the HWP interrupts causing BIOS code to freeze. HWP interrupts uses thermal LVT. Linux natively handles thermal interrupts, but in Skylake based systems SMM will take control of thermal interrupts. This is a problem for several reasons: - It is freezing in BIOS when tries to handle thermal interrupt, which will require BIOS upgrade - With SMM handling thermal we loose all the reporting features of Linux arch/x86/kernel/cpu/mcheck/therm_throt driver - Some thermal drivers like x86-package-temp driver depends on the thermal threshold interrupts - The HWP interrupts are useful for debugging and tuning performance So we need native handling of thermal interrupts. This requires some way to inform SMM that OS can handle thermal interrupts. This can be done by using _OSC/_PDC under processor scope very early in ACPI initialization flow. The bit 12 of _OSC/_PDC in processor scope defines whether OS supports handling of native interrupts for Collaborative Processor Performance Control (CPPC) notifications. Since HWP is a implementation of CPPC, setting this bit is equivalent to inform SMM that OS is capable of handling thermal interrupts. Refer to this document for details on _OSC/_PDC http://www.intel.com/content/www/us/en/standards/processor-vendor- specific-acpi-specification.html This change introduces a new function acpi_early_processor_set_osc(), which walks acpi name space and finds acpi processor object and set capability via _OSC method. Also this change writes HWP status bits to 0 to clear any HWP status bits in intel_thermal_interrupt(). Signed-off-by: Srinivas Pandruvada --- v7: Checking platform ack and setting status for successful ack and printing information message. v6: Added __init for two functions and moved dummy function to internal.h Shortened the name of the function. v5: No code change. Changed commit message to explain HWP is a implementation of CPPC. v4: Suggestion by Boris for removing use of intermediate variable for clearing HWP status and using boot_cpu_has instead of static_cpu_has v3: - Added CONFIG_X86 around static_cpu_has() to fix compile error on ARCH=ia64, reported by kbuild test robot - return AE_CTRL_TERMINATE to terminate acpi name walk space, when _OSC is set already once. v2: Unnecessary newline was introduced, removed that in acpi_processor.c arch/x86/kernel/cpu/mcheck/therm_throt.c | 3 ++ drivers/acpi/acpi_processor.c| 52 drivers/acpi/bus.c | 3 ++ drivers/acpi/internal.h | 6 4 files changed, 64 insertions(+) diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index 0b445c2..ac780ca 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c @@ -384,6 +384,9 @@ static void intel_thermal_interrupt(void) { __u64 msr_val; + if (static_cpu_has(X86_FEATURE_HWP)) + wrmsrl_safe(MSR_HWP_STATUS, 0); + rdmsrl(MSR_IA32_THERM_STATUS, msr_val); /* Check for violation of core thermal thresholds*/ diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index b5e54f2..4239b80 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -491,6 +491,58 @@ static void acpi_processor_remove(struct acpi_device *device) } #endif /* CONFIG_ACPI_HOTPLUG_CPU */ +#ifdef CONFIG_X86 +static bool acpi_hwp_native_thermal_lvt_set; +static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle, + u32 lvl, + void *context, + void **rv) +{ + u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953"; + u32 capbuf[2]; + struct acpi_osc_context osc_context = { + .uuid_str = sb_uuid_str, + .rev = 1, + .cap.length = 8, + .cap.pointer = capbuf, + }; + + if (acpi_hwp_native_thermal_lvt_set) + return AE_CTRL_TERMINATE; + + capbuf[0] = 0x; + capbuf[1] = 0x1000; /* set bit 12 */ + + if (ACPI_SUCCESS(acpi_run_osc(handle, _context))) { + if (osc_context.ret.pointer && osc_context.ret.length > 1) { + u32 *capbuf_ret = osc_context.ret.pointer; + + if (capbuf_ret[1] & 0x1000) { + acpi_handle_info(handle, + "_OSC native thermal LVT Acked\n"); + acpi_hwp_native_thermal_lvt_set = true; + } + } + kfree(osc_context.ret.pointer); + } + + return AE_OK; +} + +void __init
Re: [PATCH] sbs-battery: fix power status when battery is dry
Hi YH, On Wed, Mar 23, 2016 at 5:53 PM, YH Huangwrote: > When the battery is dry and BATTERY_FULL_DISCHARGED is set, > we should check BATTERY_DISCHARGING to decide the power status. > If BATTERY_DISCHARGING is set, the power status is not charging. > Or the power status should be charging. > > Signed-off-by: YH Huang > --- > drivers/power/sbs-battery.c | 22 -- > 1 file changed, 12 insertions(+), 10 deletions(-) > > diff --git a/drivers/power/sbs-battery.c b/drivers/power/sbs-battery.c > index d6226d6..d86db0e 100644 > --- a/drivers/power/sbs-battery.c > +++ b/drivers/power/sbs-battery.c > @@ -382,11 +382,12 @@ static int sbs_get_battery_property(struct i2c_client > *client, > > if (ret & BATTERY_FULL_CHARGED) > val->intval = POWER_SUPPLY_STATUS_FULL; > - else if (ret & BATTERY_FULL_DISCHARGED) > - val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; > - else if (ret & BATTERY_DISCHARGING) > - val->intval = POWER_SUPPLY_STATUS_DISCHARGING; > - else > + else if (ret & BATTERY_DISCHARGING) { > + if (ret & BATTERY_FULL_DISCHARGED) > + val->intval = > POWER_SUPPLY_STATUS_NOT_CHARGING; > + else > + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; > + } else I think (BATTERY_DISCHARGING && BATTERY_FULL_DISCHARGED) is still POWER_SUPPLY_STATUS_DISCHARGING. So, let's just report what the battery says and do: else if (ret & BATTERY_DISCHARGING) val->intval = POWER_SUPPLY_STATUS_DISCHARGING; > val->intval = POWER_SUPPLY_STATUS_CHARGING; > > if (chip->poll_time == 0) > @@ -702,11 +703,12 @@ static void sbs_delayed_work(struct work_struct *work) > > if (ret & BATTERY_FULL_CHARGED) > ret = POWER_SUPPLY_STATUS_FULL; > - else if (ret & BATTERY_FULL_DISCHARGED) > - ret = POWER_SUPPLY_STATUS_NOT_CHARGING; > - else if (ret & BATTERY_DISCHARGING) > - ret = POWER_SUPPLY_STATUS_DISCHARGING; > - else > + else if (ret & BATTERY_DISCHARGING) { > + if (ret & BATTERY_FULL_DISCHARGED) > + ret = POWER_SUPPLY_STATUS_NOT_CHARGING; > + else > + ret = POWER_SUPPLY_STATUS_DISCHARGING; > + } else > ret = POWER_SUPPLY_STATUS_CHARGING; > > if (chip->last_state != ret) { > -- > 1.7.9.5 >
Re: [PATCH] sbs-battery: fix power status when battery is dry
Hi YH, On Wed, Mar 23, 2016 at 5:53 PM, YH Huang wrote: > When the battery is dry and BATTERY_FULL_DISCHARGED is set, > we should check BATTERY_DISCHARGING to decide the power status. > If BATTERY_DISCHARGING is set, the power status is not charging. > Or the power status should be charging. > > Signed-off-by: YH Huang > --- > drivers/power/sbs-battery.c | 22 -- > 1 file changed, 12 insertions(+), 10 deletions(-) > > diff --git a/drivers/power/sbs-battery.c b/drivers/power/sbs-battery.c > index d6226d6..d86db0e 100644 > --- a/drivers/power/sbs-battery.c > +++ b/drivers/power/sbs-battery.c > @@ -382,11 +382,12 @@ static int sbs_get_battery_property(struct i2c_client > *client, > > if (ret & BATTERY_FULL_CHARGED) > val->intval = POWER_SUPPLY_STATUS_FULL; > - else if (ret & BATTERY_FULL_DISCHARGED) > - val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; > - else if (ret & BATTERY_DISCHARGING) > - val->intval = POWER_SUPPLY_STATUS_DISCHARGING; > - else > + else if (ret & BATTERY_DISCHARGING) { > + if (ret & BATTERY_FULL_DISCHARGED) > + val->intval = > POWER_SUPPLY_STATUS_NOT_CHARGING; > + else > + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; > + } else I think (BATTERY_DISCHARGING && BATTERY_FULL_DISCHARGED) is still POWER_SUPPLY_STATUS_DISCHARGING. So, let's just report what the battery says and do: else if (ret & BATTERY_DISCHARGING) val->intval = POWER_SUPPLY_STATUS_DISCHARGING; > val->intval = POWER_SUPPLY_STATUS_CHARGING; > > if (chip->poll_time == 0) > @@ -702,11 +703,12 @@ static void sbs_delayed_work(struct work_struct *work) > > if (ret & BATTERY_FULL_CHARGED) > ret = POWER_SUPPLY_STATUS_FULL; > - else if (ret & BATTERY_FULL_DISCHARGED) > - ret = POWER_SUPPLY_STATUS_NOT_CHARGING; > - else if (ret & BATTERY_DISCHARGING) > - ret = POWER_SUPPLY_STATUS_DISCHARGING; > - else > + else if (ret & BATTERY_DISCHARGING) { > + if (ret & BATTERY_FULL_DISCHARGED) > + ret = POWER_SUPPLY_STATUS_NOT_CHARGING; > + else > + ret = POWER_SUPPLY_STATUS_DISCHARGING; > + } else > ret = POWER_SUPPLY_STATUS_CHARGING; > > if (chip->last_state != ret) { > -- > 1.7.9.5 >
[PATCH 1/1] mm/page_alloc: Remove useless parameter of __free_pages_boot_core
From: Li Zhang__free_pages_boot_core has parameter pfn which is not used at all. So this patch is to make it clean. Signed-off-by: Li Zhang --- mm/page_alloc.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a762be5..8c0affe 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1056,8 +1056,7 @@ static void __free_pages_ok(struct page *page, unsigned int order) local_irq_restore(flags); } -static void __init __free_pages_boot_core(struct page *page, - unsigned long pfn, unsigned int order) +static void __init __free_pages_boot_core(struct page *page, unsigned int order) { unsigned int nr_pages = 1 << order; struct page *p = page; @@ -1134,7 +1133,7 @@ void __init __free_pages_bootmem(struct page *page, unsigned long pfn, { if (early_page_uninitialised(pfn)) return; - return __free_pages_boot_core(page, pfn, order); + return __free_pages_boot_core(page, order); } /* @@ -1219,12 +1218,12 @@ static void __init deferred_free_range(struct page *page, if (nr_pages == MAX_ORDER_NR_PAGES && (pfn & (MAX_ORDER_NR_PAGES-1)) == 0) { set_pageblock_migratetype(page, MIGRATE_MOVABLE); - __free_pages_boot_core(page, pfn, MAX_ORDER-1); + __free_pages_boot_core(page, MAX_ORDER-1); return; } - for (i = 0; i < nr_pages; i++, page++, pfn++) - __free_pages_boot_core(page, pfn, 0); + for (i = 0; i < nr_pages; i++, page++) + __free_pages_boot_core(page, 0); } /* Completion tracking for deferred_init_memmap() threads */ -- 2.1.0
[PATCH 1/1] mm/page_alloc: Remove useless parameter of __free_pages_boot_core
From: Li Zhang __free_pages_boot_core has parameter pfn which is not used at all. So this patch is to make it clean. Signed-off-by: Li Zhang --- mm/page_alloc.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a762be5..8c0affe 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1056,8 +1056,7 @@ static void __free_pages_ok(struct page *page, unsigned int order) local_irq_restore(flags); } -static void __init __free_pages_boot_core(struct page *page, - unsigned long pfn, unsigned int order) +static void __init __free_pages_boot_core(struct page *page, unsigned int order) { unsigned int nr_pages = 1 << order; struct page *p = page; @@ -1134,7 +1133,7 @@ void __init __free_pages_bootmem(struct page *page, unsigned long pfn, { if (early_page_uninitialised(pfn)) return; - return __free_pages_boot_core(page, pfn, order); + return __free_pages_boot_core(page, order); } /* @@ -1219,12 +1218,12 @@ static void __init deferred_free_range(struct page *page, if (nr_pages == MAX_ORDER_NR_PAGES && (pfn & (MAX_ORDER_NR_PAGES-1)) == 0) { set_pageblock_migratetype(page, MIGRATE_MOVABLE); - __free_pages_boot_core(page, pfn, MAX_ORDER-1); + __free_pages_boot_core(page, MAX_ORDER-1); return; } - for (i = 0; i < nr_pages; i++, page++, pfn++) - __free_pages_boot_core(page, pfn, 0); + for (i = 0; i < nr_pages; i++, page++) + __free_pages_boot_core(page, 0); } /* Completion tracking for deferred_init_memmap() threads */ -- 2.1.0
Re: [PATCH 3/5] perf core: Prepare writing into ring buffer from end
On 2016/3/24 3:25, Alexei Starovoitov wrote: On Wed, Mar 23, 2016 at 06:08:41PM +0800, Wangnan (F) wrote: On 2016/3/23 17:50, Peter Zijlstra wrote: On Mon, Mar 14, 2016 at 09:59:43AM +, Wang Nan wrote: Convert perf_output_begin to __perf_output_begin and make the later function able to write records from the end of the ring buffer. Following commits will utilize the 'backward' flag. This patch doesn't introduce any extra performance overhead since we use always_inline. So while I agree that with __always_inline and constant propagation we _should_ end up with the same code, we have: $ size defconfig-build/kernel/events/ring_buffer.o.{pre,post} textdata bss dec hex filename 3785 2 03787 ecb defconfig-build/kernel/events/ring_buffer.o.pre 3673 2 03675 e5b defconfig-build/kernel/events/ring_buffer.o.post The patch actually makes the file shrink. So I think we still want to have some actual performance numbers. There are some numbers. You can find them from: http://lkml.iu.edu/hypermail/linux/kernel/1601.2/03966.html Wang, when you respin, please add all perf analysis that you've done and the reasons to do it this way to commit log to make sure it stays in git history. I've reviewed it in the past and looks like the patches didn't change over the last months. So still ack, I believe overwrite buffers is a great feature. Can I add your Acked-by in all these 5 patches? Thank you.
Re: [PATCH 3/5] perf core: Prepare writing into ring buffer from end
On 2016/3/24 3:25, Alexei Starovoitov wrote: On Wed, Mar 23, 2016 at 06:08:41PM +0800, Wangnan (F) wrote: On 2016/3/23 17:50, Peter Zijlstra wrote: On Mon, Mar 14, 2016 at 09:59:43AM +, Wang Nan wrote: Convert perf_output_begin to __perf_output_begin and make the later function able to write records from the end of the ring buffer. Following commits will utilize the 'backward' flag. This patch doesn't introduce any extra performance overhead since we use always_inline. So while I agree that with __always_inline and constant propagation we _should_ end up with the same code, we have: $ size defconfig-build/kernel/events/ring_buffer.o.{pre,post} textdata bss dec hex filename 3785 2 03787 ecb defconfig-build/kernel/events/ring_buffer.o.pre 3673 2 03675 e5b defconfig-build/kernel/events/ring_buffer.o.post The patch actually makes the file shrink. So I think we still want to have some actual performance numbers. There are some numbers. You can find them from: http://lkml.iu.edu/hypermail/linux/kernel/1601.2/03966.html Wang, when you respin, please add all perf analysis that you've done and the reasons to do it this way to commit log to make sure it stays in git history. I've reviewed it in the past and looks like the patches didn't change over the last months. So still ack, I believe overwrite buffers is a great feature. Can I add your Acked-by in all these 5 patches? Thank you.