]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'agust/next' into next
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 29 Jan 2014 05:53:55 +0000 (16:53 +1100)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 29 Jan 2014 05:53:55 +0000 (16:53 +1100)
<<
Switch mpc512x to the common clock framework and adapt mpc512x
drivers to use the new clock driver. Old PPC_CLOCK code is
removed entirely since there are no users any more.
>>

1  2 
arch/powerpc/Kconfig
drivers/net/can/mscan/mpc5xxx_can.c
drivers/spi/spi-mpc512x-psc.c
include/linux/clk-provider.h

diff --combined arch/powerpc/Kconfig
index 25493a0b174cc3cbff25bfce1dfe02e6992c0b00,b131b26ca45a4af08a0bab3fe26c0c36172d5140..d15594ec213dc33cfd20baa7b01e3bd2bcec5654
@@@ -86,7 -86,6 +86,7 @@@ config PP
        bool
        default y
        select ARCH_MIGHT_HAVE_PC_PARPORT
 +      select ARCH_MIGHT_HAVE_PC_SERIO
        select BINFMT_ELF
        select OF
        select OF_EARLY_FLATTREE
        select OLD_SIGACTION if PPC32
        select HAVE_DEBUG_STACKOVERFLOW
        select HAVE_IRQ_EXIT_ON_IRQ_STACK
 +      select ARCH_USE_CMPXCHG_LOCKREF if PPC64
  
  config GENERIC_CSUM
        def_bool CPU_LITTLE_ENDIAN
@@@ -149,10 -147,6 +149,10 @@@ config EARLY_PRINT
        bool
        default y
  
 +config PANIC_TIMEOUT
 +      int
 +      default 180
 +
  config COMPAT
        bool
        default y if PPC64
@@@ -408,7 -402,8 +408,7 @@@ config KEXE
  config CRASH_DUMP
        bool "Build a kdump crash kernel"
        depends on PPC64 || 6xx || FSL_BOOKE || (44x && !SMP)
 -      select RELOCATABLE if PPC64 || 44x
 -      select DYNAMIC_MEMSTART if FSL_BOOKE
 +      select RELOCATABLE if PPC64 || 44x || FSL_BOOKE
        help
          Build a kernel suitable for use as a kdump capture kernel.
          The same kernel binary can be used as production kernel and dump
@@@ -798,7 -793,7 +798,7 @@@ config HAS_RAPIDI
        default n
  
  config RAPIDIO
 -      bool "RapidIO support"
 +      tristate "RapidIO support"
        depends on HAS_RAPIDIO || PCI
        help
          If you say Y here, the kernel will include drivers and
  
  config FSL_RIO
        bool "Freescale Embedded SRIO Controller support"
 -      depends on RAPIDIO && HAS_RAPIDIO
 +      depends on RAPIDIO = y && HAS_RAPIDIO
        default "n"
        ---help---
          Include support for RapidIO controller on Freescale embedded
@@@ -889,7 -884,7 +889,7 @@@ config DYNAMIC_MEMSTAR
  
  config RELOCATABLE
        bool "Build a relocatable kernel"
 -      depends on ADVANCED_OPTIONS && FLATMEM && 44x
 +      depends on ADVANCED_OPTIONS && FLATMEM && (44x || FSL_BOOKE)
        select NONSTATIC_KERNEL
        help
          This builds a kernel image that is capable of running at the
@@@ -1045,11 -1040,6 +1045,6 @@@ config KEYS_COMPA
  
  source "crypto/Kconfig"
  
- config PPC_CLOCK
-       bool
-       default n
-       select HAVE_CLK
  config PPC_LIB_RHEAP
        bool
  
index 035e235e31186ecc629ce4903f771fe40799f1b1,6b0c9958d824b729d74cfbbdb83713a71dd978f3..44725296f72a25b07d21bb92f9af1f0534980bc5
@@@ -16,7 -16,8 +16,7 @@@
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
 - * along with this program; if not, write to the Free Software
 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + * along with this program; if not, see <http://www.gnu.org/licenses/>.
   */
  
  #include <linux/kernel.h>
@@@ -108,135 -109,170 +108,170 @@@ static u32 mpc52xx_can_get_clock(struc
  #endif /* CONFIG_PPC_MPC52xx */
  
  #ifdef CONFIG_PPC_MPC512x
- struct mpc512x_clockctl {
-       u32 spmr;               /* System PLL Mode Reg */
-       u32 sccr[2];            /* System Clk Ctrl Reg 1 & 2 */
-       u32 scfr1;              /* System Clk Freq Reg 1 */
-       u32 scfr2;              /* System Clk Freq Reg 2 */
-       u32 reserved;
-       u32 bcr;                /* Bread Crumb Reg */
-       u32 pccr[12];           /* PSC Clk Ctrl Reg 0-11 */
-       u32 spccr;              /* SPDIF Clk Ctrl Reg */
-       u32 cccr;               /* CFM Clk Ctrl Reg */
-       u32 dccr;               /* DIU Clk Cnfg Reg */
-       u32 mccr[4];            /* MSCAN Clk Ctrl Reg 1-3 */
- };
- static struct of_device_id mpc512x_clock_ids[] = {
-       { .compatible = "fsl,mpc5121-clock", },
-       {}
- };
  static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
-                                const char *clock_name, int *mscan_clksrc)
+                                const char *clock_source, int *mscan_clksrc)
  {
-       struct mpc512x_clockctl __iomem *clockctl;
-       struct device_node *np_clock;
-       struct clk *sys_clk, *ref_clk;
-       int plen, clockidx, clocksrc = -1;
-       u32 sys_freq, val, clockdiv = 1, freq = 0;
-       const u32 *pval;
-       np_clock = of_find_matching_node(NULL, mpc512x_clock_ids);
-       if (!np_clock) {
-               dev_err(&ofdev->dev, "couldn't find clock node\n");
-               return 0;
-       }
-       clockctl = of_iomap(np_clock, 0);
-       if (!clockctl) {
-               dev_err(&ofdev->dev, "couldn't map clock registers\n");
-               goto exit_put;
-       }
+       struct device_node *np;
+       u32 clockdiv;
+       enum {
+               CLK_FROM_AUTO,
+               CLK_FROM_IPS,
+               CLK_FROM_SYS,
+               CLK_FROM_REF,
+       } clk_from;
+       struct clk *clk_in, *clk_can;
+       unsigned long freq_calc;
+       struct mscan_priv *priv;
+       struct clk *clk_ipg;
  
-       /* Determine the MSCAN device index from the peripheral's
-        * physical address. Register address offsets against the
-        * IMMR base are:  0x1300, 0x1380, 0x2300, 0x2380
+       /* the caller passed in the clock source spec that was read from
+        * the device tree, get the optional clock divider as well
         */
-       pval = of_get_property(ofdev->dev.of_node, "reg", &plen);
-       BUG_ON(!pval || plen < sizeof(*pval));
-       clockidx = (*pval & 0x80) ? 1 : 0;
-       if (*pval & 0x2000)
-               clockidx += 2;
+       np = ofdev->dev.of_node;
+       clockdiv = 1;
+       of_property_read_u32(np, "fsl,mscan-clock-divider", &clockdiv);
+       dev_dbg(&ofdev->dev, "device tree specs: clk src[%s] div[%d]\n",
+               clock_source ? clock_source : "<NULL>", clockdiv);
+       /* when clock-source is 'ip', the CANCTL1[CLKSRC] bit needs to
+        * get set, and the 'ips' clock is the input to the MSCAN
+        * component
+        *
+        * for clock-source values of 'ref' or 'sys' the CANCTL1[CLKSRC]
+        * bit needs to get cleared, an optional clock-divider may have
+        * been specified (the default value is 1), the appropriate
+        * MSCAN related MCLK is the input to the MSCAN component
+        *
+        * in the absence of a clock-source spec, first an optimal clock
+        * gets determined based on the 'sys' clock, if that fails the
+        * 'ref' clock is used
+        */
+       clk_from = CLK_FROM_AUTO;
+       if (clock_source) {
+               /* interpret the device tree's spec for the clock source */
+               if (!strcmp(clock_source, "ip"))
+                       clk_from = CLK_FROM_IPS;
+               else if (!strcmp(clock_source, "sys"))
+                       clk_from = CLK_FROM_SYS;
+               else if (!strcmp(clock_source, "ref"))
+                       clk_from = CLK_FROM_REF;
+               else
+                       goto err_invalid;
+               dev_dbg(&ofdev->dev, "got a clk source spec[%d]\n", clk_from);
+       }
+       if (clk_from == CLK_FROM_AUTO) {
+               /* no spec so far, try the 'sys' clock; round to the
+                * next MHz and see if we can get a multiple of 16MHz
+                */
+               dev_dbg(&ofdev->dev, "no clk source spec, trying SYS\n");
+               clk_in = devm_clk_get(&ofdev->dev, "sys");
+               if (IS_ERR(clk_in))
+                       goto err_notavail;
+               freq_calc = clk_get_rate(clk_in);
+               freq_calc +=  499999;
+               freq_calc /= 1000000;
+               freq_calc *= 1000000;
+               if ((freq_calc % 16000000) == 0) {
+                       clk_from = CLK_FROM_SYS;
+                       clockdiv = freq_calc / 16000000;
+                       dev_dbg(&ofdev->dev,
+                               "clk fit, sys[%lu] div[%d] freq[%lu]\n",
+                               freq_calc, clockdiv, freq_calc / clockdiv);
+               }
+       }
+       if (clk_from == CLK_FROM_AUTO) {
+               /* no spec so far, use the 'ref' clock */
+               dev_dbg(&ofdev->dev, "no clk source spec, trying REF\n");
+               clk_in = devm_clk_get(&ofdev->dev, "ref");
+               if (IS_ERR(clk_in))
+                       goto err_notavail;
+               clk_from = CLK_FROM_REF;
+               freq_calc = clk_get_rate(clk_in);
+               dev_dbg(&ofdev->dev,
+                       "clk fit, ref[%lu] (no div) freq[%lu]\n",
+                       freq_calc, freq_calc);
+       }
  
-       /*
-        * Clock source and divider selection: 3 different clock sources
-        * can be selected: "ip", "ref" or "sys". For the latter two, a
-        * clock divider can be defined as well. If the clock source is
-        * not specified by the device tree, we first try to find an
-        * optimal CAN source clock based on the system clock. If that
-        * is not posslible, the reference clock will be used.
+       /* select IPS or MCLK as the MSCAN input (returned to the caller),
+        * setup the MCLK mux source and rate if applicable, apply the
+        * optionally specified or derived above divider, and determine
+        * the actual resulting clock rate to return to the caller
         */
-       if (clock_name && !strcmp(clock_name, "ip")) {
+       switch (clk_from) {
+       case CLK_FROM_IPS:
+               clk_can = devm_clk_get(&ofdev->dev, "ips");
+               if (IS_ERR(clk_can))
+                       goto err_notavail;
+               priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+               priv->clk_can = clk_can;
+               freq_calc = clk_get_rate(clk_can);
                *mscan_clksrc = MSCAN_CLKSRC_IPS;
-               freq = mpc5xxx_get_bus_frequency(ofdev->dev.of_node);
-       } else {
+               dev_dbg(&ofdev->dev, "clk from IPS, clksrc[%d] freq[%lu]\n",
+                       *mscan_clksrc, freq_calc);
+               break;
+       case CLK_FROM_SYS:
+       case CLK_FROM_REF:
+               clk_can = devm_clk_get(&ofdev->dev, "mclk");
+               if (IS_ERR(clk_can))
+                       goto err_notavail;
+               priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+               priv->clk_can = clk_can;
+               if (clk_from == CLK_FROM_SYS)
+                       clk_in = devm_clk_get(&ofdev->dev, "sys");
+               if (clk_from == CLK_FROM_REF)
+                       clk_in = devm_clk_get(&ofdev->dev, "ref");
+               if (IS_ERR(clk_in))
+                       goto err_notavail;
+               clk_set_parent(clk_can, clk_in);
+               freq_calc = clk_get_rate(clk_in);
+               freq_calc /= clockdiv;
+               clk_set_rate(clk_can, freq_calc);
+               freq_calc = clk_get_rate(clk_can);
                *mscan_clksrc = MSCAN_CLKSRC_BUS;
-               pval = of_get_property(ofdev->dev.of_node,
-                                      "fsl,mscan-clock-divider", &plen);
-               if (pval && plen == sizeof(*pval))
-                       clockdiv = *pval;
-               if (!clockdiv)
-                       clockdiv = 1;
-               if (!clock_name || !strcmp(clock_name, "sys")) {
-                       sys_clk = devm_clk_get(&ofdev->dev, "sys_clk");
-                       if (IS_ERR(sys_clk)) {
-                               dev_err(&ofdev->dev, "couldn't get sys_clk\n");
-                               goto exit_unmap;
-                       }
-                       /* Get and round up/down sys clock rate */
-                       sys_freq = 1000000 *
-                               ((clk_get_rate(sys_clk) + 499999) / 1000000);
-                       if (!clock_name) {
-                               /* A multiple of 16 MHz would be optimal */
-                               if ((sys_freq % 16000000) == 0) {
-                                       clocksrc = 0;
-                                       clockdiv = sys_freq / 16000000;
-                                       freq = sys_freq / clockdiv;
-                               }
-                       } else {
-                               clocksrc = 0;
-                               freq = sys_freq / clockdiv;
-                       }
-               }
-               if (clocksrc < 0) {
-                       ref_clk = devm_clk_get(&ofdev->dev, "ref_clk");
-                       if (IS_ERR(ref_clk)) {
-                               dev_err(&ofdev->dev, "couldn't get ref_clk\n");
-                               goto exit_unmap;
-                       }
-                       clocksrc = 1;
-                       freq = clk_get_rate(ref_clk) / clockdiv;
-               }
+               dev_dbg(&ofdev->dev, "clk from MCLK, clksrc[%d] freq[%lu]\n",
+                       *mscan_clksrc, freq_calc);
+               break;
+       default:
+               goto err_invalid;
        }
  
-       /* Disable clock */
-       out_be32(&clockctl->mccr[clockidx], 0x0);
-       if (clocksrc >= 0) {
-               /* Set source and divider */
-               val = (clocksrc << 14) | ((clockdiv - 1) << 17);
-               out_be32(&clockctl->mccr[clockidx], val);
-               /* Enable clock */
-               out_be32(&clockctl->mccr[clockidx], val | 0x10000);
-       }
+       /* the above clk_can item is used for the bitrate, access to
+        * the peripheral's register set needs the clk_ipg item
+        */
+       clk_ipg = devm_clk_get(&ofdev->dev, "ipg");
+       if (IS_ERR(clk_ipg))
+               goto err_notavail_ipg;
+       if (clk_prepare_enable(clk_ipg))
+               goto err_notavail_ipg;
+       priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+       priv->clk_ipg = clk_ipg;
+       /* return the determined clock source rate */
+       return freq_calc;
+ err_invalid:
+       dev_err(&ofdev->dev, "invalid clock source specification\n");
+       /* clock source rate could not get determined */
+       return 0;
  
-       /* Enable MSCAN clock domain */
-       val = in_be32(&clockctl->sccr[1]);
-       if (!(val & (1 << 25)))
-               out_be32(&clockctl->sccr[1], val | (1 << 25));
+ err_notavail:
+       dev_err(&ofdev->dev, "cannot acquire or setup bitrate clock source\n");
+       /* clock source rate could not get determined */
+       return 0;
  
-       dev_dbg(&ofdev->dev, "using '%s' with frequency divider %d\n",
-               *mscan_clksrc == MSCAN_CLKSRC_IPS ? "ips_clk" :
-               clocksrc == 1 ? "ref_clk" : "sys_clk", clockdiv);
+ err_notavail_ipg:
+       dev_err(&ofdev->dev, "cannot acquire or setup register clock\n");
+       /* clock source rate could not get determined */
+       return 0;
+ }
  
- exit_unmap:
-       iounmap(clockctl);
- exit_put:
-       of_node_put(np_clock);
-       return freq;
+ static void mpc512x_can_put_clock(struct platform_device *ofdev)
+ {
+       struct mscan_priv *priv;
+       priv = netdev_priv(dev_get_drvdata(&ofdev->dev));
+       if (priv->clk_ipg)
+               clk_disable_unprepare(priv->clk_ipg);
  }
  #else /* !CONFIG_PPC_MPC512x */
  static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
  {
        return 0;
  }
+ #define mpc512x_can_put_clock NULL
  #endif /* CONFIG_PPC_MPC512x */
  
  static const struct of_device_id mpc5xxx_can_table[];
@@@ -385,11 -422,13 +421,13 @@@ static int mpc5xxx_can_resume(struct pl
  static const struct mpc5xxx_can_data mpc5200_can_data = {
        .type = MSCAN_TYPE_MPC5200,
        .get_clock = mpc52xx_can_get_clock,
+       /* .put_clock not applicable */
  };
  
  static const struct mpc5xxx_can_data mpc5121_can_data = {
        .type = MSCAN_TYPE_MPC5121,
        .get_clock = mpc512x_can_get_clock,
+       .put_clock = mpc512x_can_put_clock,
  };
  
  static const struct of_device_id mpc5xxx_can_table[] = {
index 46d2313f7c6fc1e155ff15c7f60962291c923524,de66c676c2487655e75f7774cb5e3437c3f7048f..5032141eeeec4ee0cbb46b7d7af7c8a65e76212c
@@@ -40,6 -40,7 +40,7 @@@ struct mpc512x_psc_spi 
        unsigned int irq;
        u8 bits_per_word;
        struct clk *clk_mclk;
+       struct clk *clk_ipg;
        u32 mclk_rate;
  
        struct completion txisrdone;
@@@ -475,8 -476,6 +476,6 @@@ static int mpc512x_psc_spi_do_probe(str
        struct spi_master *master;
        int ret;
        void *tempp;
-       int psc_num;
-       char clk_name[16];
        struct clk *clk;
  
        master = spi_alloc_master(dev, sizeof *mps);
        master->cleanup = mpc512x_psc_spi_cleanup;
        master->dev.of_node = dev->of_node;
  
 -      tempp = ioremap(regaddr, size);
 +      tempp = devm_ioremap(dev, regaddr, size);
        if (!tempp) {
                dev_err(dev, "could not ioremap I/O port range\n");
                ret = -EFAULT;
        mps->psc = tempp;
        mps->fifo =
                (struct mpc512x_psc_fifo *)(tempp + sizeof(struct mpc52xx_psc));
 -
 -      ret = request_irq(mps->irq, mpc512x_psc_spi_isr, IRQF_SHARED,
 -                        "mpc512x-psc-spi", mps);
 +      ret = devm_request_irq(dev, mps->irq, mpc512x_psc_spi_isr, IRQF_SHARED,
 +                              "mpc512x-psc-spi", mps);
        if (ret)
                goto free_master;
        init_completion(&mps->txisrdone);
  
-       psc_num = master->bus_num;
-       snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num);
-       clk = devm_clk_get(dev, clk_name);
+       clk = devm_clk_get(dev, "mclk");
        if (IS_ERR(clk)) {
                ret = PTR_ERR(clk);
 -              goto free_irq;
 +              goto free_master;
        }
        ret = clk_prepare_enable(clk);
        if (ret)
 -              goto free_irq;
 +              goto free_master;
        mps->clk_mclk = clk;
        mps->mclk_rate = clk_get_rate(clk);
  
+       clk = devm_clk_get(dev, "ipg");
+       if (IS_ERR(clk)) {
+               ret = PTR_ERR(clk);
+               goto free_mclk_clock;
+       }
+       ret = clk_prepare_enable(clk);
+       if (ret)
+               goto free_mclk_clock;
+       mps->clk_ipg = clk;
        ret = mpc512x_psc_spi_port_config(master, mps);
        if (ret < 0)
-               goto free_clock;
+               goto free_ipg_clock;
  
        ret = devm_spi_register_master(dev, master);
        if (ret < 0)
-               goto free_clock;
+               goto free_ipg_clock;
  
        return ret;
  
- free_clock:
+ free_ipg_clock:
+       clk_disable_unprepare(mps->clk_ipg);
+ free_mclk_clock:
        clk_disable_unprepare(mps->clk_mclk);
 -free_irq:
 -      free_irq(mps->irq, mps);
  free_master:
 -      if (mps->psc)
 -              iounmap(mps->psc);
        spi_master_put(master);
  
        return ret;
  
  static int mpc512x_psc_spi_do_remove(struct device *dev)
  {
 -      struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
 +      struct spi_master *master = dev_get_drvdata(dev);
        struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
  
        clk_disable_unprepare(mps->clk_mclk);
 -      free_irq(mps->irq, mps);
 -      if (mps->psc)
 -              iounmap(mps->psc);
+       clk_disable_unprepare(mps->clk_ipg);
  
        return 0;
  }
index 999b28ba38f7270608452cfff436a4e52b22a918,534dc618f2d73314ef5374aff6b0eb27c89225a1..f1a098a4450c0849cdf2fab128d179b92e98d0bc
@@@ -29,7 -29,6 +29,7 @@@
  #define CLK_IS_BASIC          BIT(5) /* Basic clk, can't do a to_clk_foo() */
  #define CLK_GET_RATE_NOCACHE  BIT(6) /* do not use the cached clk rate */
  #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
 +#define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
  
  struct clk_hw;
  
   *            which is likely helpful for most .set_rate implementation.
   *            Returns 0 on success, -EERROR otherwise.
   *
 + * @recalc_accuracy: Recalculate the accuracy of this clock. The clock accuracy
 + *            is expressed in ppb (parts per billion). The parent accuracy is
 + *            an input parameter.
 + *            Returns the calculated accuracy.  Optional - if this op is not
 + *            set then clock accuracy will be initialized to parent accuracy
 + *            or 0 (perfect clock) if clock has no parent.
 + *
 + * @set_rate_and_parent: Change the rate and the parent of this clock. The
 + *            requested rate is specified by the second argument, which
 + *            should typically be the return of .round_rate call.  The
 + *            third argument gives the parent rate which is likely helpful
 + *            for most .set_rate_and_parent implementation. The fourth
 + *            argument gives the parent index. This callback is optional (and
 + *            unnecessary) for clocks with 0 or 1 parents as well as
 + *            for clocks that can tolerate switching the rate and the parent
 + *            separately via calls to .set_parent and .set_rate.
 + *            Returns 0 on success, -EERROR otherwise.
 + *
 + *
   * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow
   * implementations to split any work between atomic (enable) and sleepable
   * (prepare) contexts.  If enabling a clock requires code that might sleep,
@@@ -159,11 -139,6 +159,11 @@@ struct clk_ops 
        u8              (*get_parent)(struct clk_hw *hw);
        int             (*set_rate)(struct clk_hw *hw, unsigned long,
                                    unsigned long);
 +      int             (*set_rate_and_parent)(struct clk_hw *hw,
 +                                  unsigned long rate,
 +                                  unsigned long parent_rate, u8 index);
 +      unsigned long   (*recalc_accuracy)(struct clk_hw *hw,
 +                                         unsigned long parent_accuracy);
        void            (*init)(struct clk_hw *hw);
  };
  
@@@ -219,7 -194,6 +219,7 @@@ struct clk_hw 
  struct clk_fixed_rate {
        struct          clk_hw hw;
        unsigned long   fixed_rate;
 +      unsigned long   fixed_accuracy;
        u8              flags;
  };
  
@@@ -227,9 -201,6 +227,9 @@@ extern const struct clk_ops clk_fixed_r
  struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                unsigned long fixed_rate);
 +struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
 +              const char *name, const char *parent_name, unsigned long flags,
 +              unsigned long fixed_rate, unsigned long fixed_accuracy);
  
  void of_fixed_clk_setup(struct device_node *np);
  
@@@ -462,7 -433,6 +462,7 @@@ struct clk *clk_get_parent_by_index(str
  unsigned int __clk_get_enable_count(struct clk *clk);
  unsigned int __clk_get_prepare_count(struct clk *clk);
  unsigned long __clk_get_rate(struct clk *clk);
 +unsigned long __clk_get_accuracy(struct clk *clk);
  unsigned long __clk_get_flags(struct clk *clk);
  bool __clk_is_prepared(struct clk *clk);
  bool __clk_is_enabled(struct clk *clk);
@@@ -542,6 -512,20 +542,20 @@@ static inline const char *of_clk_get_pa
   * for improved portability across platforms
   */
  
+ #if IS_ENABLED(CONFIG_PPC)
+ static inline u32 clk_readl(u32 __iomem *reg)
+ {
+       return ioread32be(reg);
+ }
+ static inline void clk_writel(u32 val, u32 __iomem *reg)
+ {
+       iowrite32be(val, reg);
+ }
+ #else /* platform dependent I/O accessors */
  static inline u32 clk_readl(u32 __iomem *reg)
  {
        return readl(reg);
@@@ -552,5 -536,7 +566,7 @@@ static inline void clk_writel(u32 val, 
        writel(val, reg);
  }
  
+ #endif        /* platform dependent I/O accessors */
  #endif /* CONFIG_COMMON_CLK */
  #endif /* CLK_PROVIDER_H */